- ベストアンサー
エクセルVBA If~Then~Elseの使い方|条件分岐による文字列の結合処理
- エクセルのVBAを使用して文字列の結合処理を行う際に、条件分岐を使用する方法を解説します。
- 具体的な処理内容は、文字列の最後の数字と次のセルの最初の数字が連続している場合には、互いに消去して結合し、連続していない場合にはカンマでつなげて結合します。
- しかし、現在のプログラムではループ中の1回目の条件分岐が成功するものの、2回目以降は適切な結果を得ることができていません。プロパティの使い方やロジックに誤りがある可能性があるため、詳細な解決方法についてはわかりません。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>X = Cells(i, 1)はなぜ1回しか実行されないのでしょうか。 ループの外の「1回しか通らない所に書いた」からです。 >ループ内でX = Cells(i, 1)を使うたびに、i = i + 1を利用することになるので >X = Cells(4, 1) → Cells(5, 1) → Cells(6, 1) >となるんではないかと思ったのですが。 なりません。 「代入文」は「左辺の変数=右辺の式」と言う形ですが「今の『右辺の式』の値を『左辺の変数』に代入する」ことしかしません。 「代入した後で、右辺の式の値が変わったら、自動的に左辺の変数の値も変える」と言う事はしません。 「一回やったら、それっきり」なのです。 例えば「一回前のiの値を、Yに保存しておく」という場合 i = 3 Y = i i = i + 1 と書きます。 「Yへの代入は、一回やったら、それっきり」ですから「i を変える前に、Yに入れておく」という方法で「一回前のiの値を、Yに保存しておく」ことが出来ます。 もし、これで「iの値を変えたら、勝手にYの値も変わる」のであれば「iを変える前の値をYにとって置く事が出来なくなってしまう」という問題が発生します。 あなたのプログラムの「X」も同じように「Xへの代入は、一回やったら、それっきり」なのです。 ですから「iの値を変えたら、X = Cells(i,1)の代入文を、毎回やり直ししないといけない」のです。
その他の回答 (3)
- kagakusuki
- ベストアンサー率51% (2610/5101)
・質問者の乗せたコードの添削になっていない ・変数名が質問者のものと違う というものでも宜しければ、下記の様なやり方もあります。 Sub QNo9157364_エクセル_VBA_If_Then_Else() Const OutputCell = "A1" Const FirstCell = "A2" Dim myRange As Range, myString As String, _ c As Range, buf As Variant, tempArray As Variant With Range(FirstCell) If .Value = "" Then MsgBox "処理すべきデータがありません。" & vbCrLf _ & "マクロを終了します。", vbOKOnly, "データ無し" Exit Sub End If If .Offset(1).Value = "" Then Set myRange = .Offset(0) Else Set myRange = Range(.Offset(0), .End(xlDown)) End If End With buf = -9 For Each c In myRange tempArray = Split(c.Value & "-", "-") myString = myString & "-" If IsNumeric(tempArray(0)) And IsNumeric(tempArray(1)) _ And Not c.Value Like "*-*-*" Then If tempArray(0) - buf <> 1 Then _ myString = myString & buf & "," & tempArray(0) buf = tempArray(1) Else c.Select MsgBox "既定のパターンに合致しないデータがあるため" _ & "処理を行う事が出来ません。" & vbCrLf _ & "マクロを終了します。", vbOKOnly, "無効なデータ" Exit Sub End If Next c myString = Mid(myString, 5) & buf & "-" & tempArray(1) Range(OutputCell).Value = myString End Sub
- imogasi
- ベストアンサー率27% (4737/17069)
・質問者の乗せたコードの添削になっていない ・変数名が質問者のものと違う のですが、下記コードをやってみる気があれば、やってみてくだされば幸いです。 ーー 下記を仮定し、チェックは行っていない。 ・セルデータは3けた数字とハイフンと3桁数字 ・データは昇順になっている。減少することはない。 ・文字列の長さの制限を越えない程度のセル数である ・正しいと思われれば、Msgboxは外すこと。 ーー Sub test01() s = "" '連続中の文字列 ss = "" '飛んだ目までの出来上がった文字列 lr = Range("A10000").End(xlUp).Row For i = 2 To lr x = Cells(i, "A") y = Split(x, "-") 'y(0)とy(1)にわかれる MsgBox "セルの値" & y(0) & "-" & y(1) '毎セルの値確認用 If i = 2 Then '最初行は特別 s = Cells(i, "A") 'そのままsに m = Val(y(1)) '最終はm(数値で)保存 f = Trim(Str(y(0))) '一続きの最初 s = ss & f & "-" & Trim(Str(m)) MsgBox s GoTo p1 End If '以下sは、そのセルの都度出来上がった文字列確認 If Val(y(0)) = m + 1 Then '次の正整数 m = y(1) s = ss & f & "-" & Trim(Str(m)) MsgBox s Else ' 飛んだ ss = s & "," f = Trim(Str(y(0))) s = ss & y(0) & "-" & y(1) ' f & "-" & Trim(Str(m)) & MsgBox s m = y(1) End If p1: Next i Cells(1, "A") = s End Sub テストデータ 100-202 203-206 207-211 212-215 218-223 225-226 227-230 231-233 235-238 ーー A1セル 100-215,218-223,225-233,235-238 ーー いったんカンマを挟んで文字列をすべて結合し、続いている部分の文字列を省くようなロジックでもできそうかと思ったが、やってない。 ごたごたしない(IFブロックの少ない)、すっきりしたロジックはないものかな、と思ったが、時間もなく、私には無理のよう。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
X = Cells(i, 1) は1回しか実行されません。ずっと「102-103」が入ったままです。 X = Cells(i, 1) の位置を変えましょう。 Dim i As Integer Dim X As String Dim mojisu As String i = 3 mojisu = 3 Cells(1, 1) = Cells(2, 1) Do Until Cells(i, 1).Value = "" X = Cells(i, 1) If Left(X, mojisu) - Right(Cells(1, 1), mojisu) = 1 Then Cells(1, 1).Value = Left(Cells(1, 1), Len(Cells(1, 1)) - mojisu) & Right(X, Len(X) - mojisu) Else Cells(1, 1).Value = Cells(1, 1).Value & "," & Cells(i, 1).Value End If i = i + 1 Loop
お礼
ありがとうございます。 前回の質問にも回答いただき、今回もありがとうございます。 ご指摘どおりに直すと成功しました。 あっさり!しかしなぜ?なのでしょうか。 X = Cells(i, 1)はなぜ1回しか実行されないのでしょうか。 ループ内でX = Cells(i, 1)を使うたびに、i = i + 1を利用することになるので X = Cells(4, 1) → Cells(5, 1) → Cells(6, 1) となるんではないかと思ったのですが。
お礼
ありがとうございます。 なるほど、 i に 3 を代入して、X が Cells(3, 1) になったら、定義し直さない限り X は Cells(3, 1) という定数のままなのですね。 プロセスの考え方が根本的に違っていたようです。 大変ためになりました。