エクセルVBA If~Then~Elseの使い方|条件分岐による文字列の結合処理

このQ&Aのポイント
  • エクセルのVBAを使用して文字列の結合処理を行う際に、条件分岐を使用する方法を解説します。
  • 具体的な処理内容は、文字列の最後の数字と次のセルの最初の数字が連続している場合には、互いに消去して結合し、連続していない場合にはカンマでつなげて結合します。
  • しかし、現在のプログラムではループ中の1回目の条件分岐が成功するものの、2回目以降は適切な結果を得ることができていません。プロパティの使い方やロジックに誤りがある可能性があるため、詳細な解決方法についてはわかりません。
回答を見る
  • ベストアンサー

エクセル VBA If~Then~Else

エクセルのA列に以下の文字列が入っています。 A1 A2=100-101 A3=102-103 A4=104-105 A5=106-107 A列の文字列を上から順に結合するため下記のVBAを実行しました。 結合の条件として、文字列の最後の数字と次のセルの最初の数字が連続しているならば、互いに消去して結合、そうでないなら「,」 (カンマ)でつなげて結合したいと思っています。 なので期待する結果としては A1=100----107 となってほしいのですが、実際は A1=100--103,104-105,106-107 となってしまいました。 (ループ中の1回目の条件分岐だけが成功し、2回目以降は違っている) 「IF~Then」の部分が間違っているようなのですが・・・・・わかりません。 プロパティの使い方など全体的に至らぬ点があるかもしれませんがよろしくお願いします。 Dim i As Integer Dim X As String Dim mojisu As String i = 3 X = Cells(i, 1) mojisu = 3 Cells(1, 1) = Cells(2, 1) Do Until Cells(i, 1).Value = "" 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

  • fisica
  • お礼率77% (235/305)

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8522/19371)
回答No.3

>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)の代入文を、毎回やり直ししないといけない」のです。

fisica
質問者

お礼

ありがとうございます。 なるほど、 i に 3 を代入して、X が Cells(3, 1) になったら、定義し直さない限り X は Cells(3, 1) という定数のままなのですね。 プロセスの考え方が根本的に違っていたようです。 大変ためになりました。

その他の回答 (3)

  • kagakusuki
  • ベストアンサー率51% (2610/5101)
回答No.4

・質問者の乗せたコードの添削になっていない ・変数名が質問者のものと違う というものでも宜しければ、下記の様なやり方もあります。 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/17068)
回答No.2

・質問者の乗せたコードの添削になっていない ・変数名が質問者のものと違う のですが、下記コードをやってみる気があれば、やってみてくだされば幸いです。 ーー 下記を仮定し、チェックは行っていない。 ・セルデータは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ブロックの少ない)、すっきりしたロジックはないものかな、と思ったが、時間もなく、私には無理のよう。

  • chie65535
  • ベストアンサー率43% (8522/19371)
回答No.1

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

fisica
質問者

お礼

ありがとうございます。 前回の質問にも回答いただき、今回もありがとうございます。 ご指摘どおりに直すと成功しました。 あっさり!しかしなぜ?なのでしょうか。 X = Cells(i, 1)はなぜ1回しか実行されないのでしょうか。 ループ内でX = Cells(i, 1)を使うたびに、i = i + 1を利用することになるので X = Cells(4, 1) → Cells(5, 1) → Cells(6, 1) となるんではないかと思ったのですが。

関連するQ&A

  • Excel VBAでIF~Thenの入れ子がうまくできません。

    いつもお世話になってます。 IF~Then~EndIfにIFを入れていますがうまくいきません。よろしくお願いします。 Private Sub CommandButton10_Click() Dim i As Long Dim 最終行 As String Dim サーチ行 As Long Dim 行 As Long Dim 列 As Long If TextBox33.Value = "" Then MsgBox "使用量を入力してください。" Else If TextBox11 <> "" Then TextBox26 = TextBox33 * TextBox11 / 100 '成分1 End If If TextBox12 <> "" Then TextBox25 = TextBox33 * TextBox12 / 100 '成分2 End If Workbooks.Open Filename:=ThisWorkbook.Path & "\データ物質試薬管理.xls" Sheets("shinki").Activate 最終行 = (Range("B2").End(xlDown).Row) '商品名の行検索 サーチ行 = 0 For i = 2 To 最終行 If ComboBox3.Value = Range("B" & i) Then Workbooks("データ物質試薬管理.xls").Close savechanges:=False '保存しない Workbooks.Open Filename:=ThisWorkbook.Path & "\データ物質試薬管理.xls" Sheets("kongou").Select Range("A65536").End(xlUp).Offset(1).Select 行 = ActiveCell.Row 列 = ActiveCell.Column Cells(行, 列) = UserForm11.TextBox16.Value 'CAS Cells(行, 列 + 1) = UserForm11.TextBox21.Value '使用日 Cells(行, 列 + 2) = UserForm11.TextBox29.Value '使用者 Cells(行, 列 + 4) = UserForm11.TextBox26.Value '成分1使用量 Cells(行 + 2, 列) = UserForm11.TextBox18.Value 'CAS Cells(行 + 2, 列 + 1) = UserForm11.TextBox21.Value '使用日 Cells(行 + 2, 列 + 2) = UserForm11.TextBox29.Value '使用者 Cells(行 + 2, 列 + 4) = UserForm11.TextBox24.Value '成分3使用量 Cells(行 + 2, 列 + 5) = UserForm11.TextBox32.Value '種類 Cells(行 + 2, 列 + 6) = UserForm11.TextBox34.Value '単位 Cells(行 + 2, 列 + 7) = UserForm11.ComboBox3.Value '商品名 Workbooks("データ物質試薬管理.xls").Close savechanges:=True 'showhinに在庫管理する Workbooks.Open Filename:=ThisWorkbook.Path & "\データ物質試薬管理.xls" Sheets("showhin").Select Range("A65536").End(xlUp).Offset(1).Select 行 = ActiveCell.Row 列 = ActiveCell.Column Cells(行, 列) = UserForm11.TextBox2.Value '品名コード Cells(行, 列 + 1) = UserForm11.ComboBox3.Value '商品名 'Cells(行, 列 + 2) = UserForm9.TextBox3.Value '1本の量 'Cells(行, 列 + 3) = UserForm9.TextBox4.Value '本数 Cells(行, 列 + 4) = UserForm11.TextBox34.Value '単位 Cells(行, 列 + 5) = UserForm11.TextBox32.Value '種別 Cells(行, 列 + 6) = UserForm11.TextBox21.Value '使用日 Cells(行, 列 + 7) = UserForm11.TextBox29.Value '使用者名 Cells(行, 列 + 9) = UserForm11.TextBox33.Value '使用量 Workbooks("データ物質試薬管理.xls").Close savechanges:=True MsgBox "登録しました。" End If サーチ行 = i Exit For 'End If Next If サーチ行 = 0 Then MsgBox ComboBox3.Value & "商品は登録されておりません。" & Chr(10) & "「新規商品登録」ボタンから入力してください。" End If End If If TextBox21.Value = "" Then '使用量 MsgBox "使用日を入力してください。" End If ComboBox3.SetFocus End Sub

  • Excel VBA IF文がうまく動作しないわけがわかりません…

    未熟な私ですが… セルC2の文字列の6・7桁目に入っている文字により、8桁目の文字を 置き換えるものをつくりました。 例えば、セルのC2に、IRCD-311234 という値があれば IRCD-31A234 にしなさいというものです しかし、 ElseIf の条件式にあてはまるものがでてきても、 すべて最初のIFの条件式にしてしまい、Elseifに反応してくれません。 ****************************************************** Sub 変換() Dim DAT As Range Dim CAR As String If Mid(Range("C2").Value, 6, 2) = 31 Or 32 Or 33 Then For Each DAT In Range("A1:P40")     CAR = CStr(DAT) If Left(CAR, 5) = "IRCD-" Then    CAR = Left(CAR, 7) & "A" & Right(CAR, Len(CAR) - 8)  DAT.Value = CAR End If Next ElseIf Mid(Range("C2").Value, 6, 2) = 37 Or 38 Or 39 Then For Each DAT In Range("A1:P40") CAR = CStr(DAT) If Left(CAR, 5) = "IRCD-" Then CAR = Left(CAR, 7) & "B" & Right(CAR, Len(CAR) - 8) DAT.Value = CAR End If Next  End If  End Sub ****************************************************** 本やネットを見ているのですが、何が悪いのか私にはわかりません…。 どうかご指導をお願いいたします。

  • エクセルVBAのIF・・・Else文について

    A列に日付が入っていて、それが12月の時はF列に"○"、 それ以外は"×"と表示したいのですが、下記を実行すると、 A列の空白セルの時もF列に"○"が表示されます。 何故でしょうか。Offsetを使って作成したいのですが、 すみませんが、宜しく御願いします。 Sub Test()  Dim i   For i = 2 To 20    If Month(Cells(i, 1)) = 12 Then     Cells(i, 1).Offset(0, 6) = "○"    Else     Cells(i, 1).Offset(0, 6) = "×"    End If   Next End Sub

  • VBA 文字列に関して

    現在 A22のセルに入力された文字列をボタンを押せば ばらばらにしてA22のセルから順番に入れるマクロを作りました (例)A22のセルに ”こんにちわ”の文字列が入っている場合 ボタン押下   ↓ A22のセル⇒こ B22のセル⇒ん C22のセル⇒に D22のセル⇒ち E22のセル⇒わ になる。 不思議なことに数字を16文字以上いれてボタンを押し文字を分離すると入力していない文字、数字が入ってしまいます。 数字だけこういう現象が発生してしまいます。 例えば "1111111111111111"と入力して文字を分離した場合 1.11111111111111E+15と個々のセルに格納されます。 原因がわかる方、教えて頂けないでしょうか? 以下がコードです。宜しくお願い致します。 Private Sub CommandButton1_Click()   Dim one As String   Dim myString As String   myString = Cells(22, 1)   numString = Len(Cells(22, 1))   If Len(myString) <= 50 Then    For i = 1 To Len(Range("A22").Value)      one = String(1, myString)      Cells(22, i) = one      myString = Replace(myString, one, "", 1, 1, vbTextCompare)    Next i   End If End Sub

  • VBAでのデータ転記(再)

    データがsheet1に縦記述で書いてあります。 C列 D列 ああ A01 いい A02 うう A03 . ささ B01 しし B02 すす B03 . はは AA01 ひひ AA02 ふふ AA03 . やや AB01 ゆゆ AB02 よよ AB03 . D列を元にしてC列の文字列をsheet2に以下のように並べたいです。D列はアドレス扱いででアルファベットが変わったら改行してデータを並べるようにします。 A列  B列 C列 ああ いい うう・ ささ しし すす・ ・・・・・ はは ひひ ふふ・ やや ゆゆ よよ・ 作成したコード Dim I As Integer, MAE As String, IMA As String, TEMP2 As String Dim X1 As Integer, Y1 As Integer, X3 As Integer, Y3 As Integer, PINNAME As String X1 = 4: Y1 = 2 X3 = 1: Y3 = 1 MAE = Sheets("Sheet1").Cells(Y1, X1) Do PINNAME = Sheets("Sheet1").Cells(Y1, X1 - 1) IMA = Sheets("Sheet1").Cells(Y1, X1) '今の値が入っている If IMA = "" Then Exit Do End If If Left(MAE, 1) <> Left(IMA, 1) Then Y3 = Y3 + 1: X3 = 1 Sheets("Sheet2").Cells(Y3, X3).Value = PINNAME X3 = X3 + 1 Else Sheets("Sheet2").Cells(Y3, X3).Value = PINNAME X3 = X3 + 1 End If MAE = Sheets("Sheet1").Cells(Y1, X1) Y1 = Y1 + 1 Loop Until IMA = "" Left関数でアドレスの左1文字を前後のセルで比較して異なる場合、改行する方法を考えましたが、AA01 AA02・・・がムリです。このコードに補足すればできるでしょうか?それとも別の考え方で行った方がいいでしょうか? 初心者レベルなので考え方も教えて下さい。宜しくお願いします。

  • エクセルVBA

    A列を基準にBC列が空白ならAの数値を入れて、A>BならB列を更新、A<CならC列を更新 A列が数値以外ならその行をスキップ、という処理をしたいのですが Option Explicit Dim A As Range, B As Range, C As Range Dim i As Long Sub test() For i = 1 To 10 Set A = Cells(i, 1) Set B = A.Offset(0, 1) Set C = A.Offset(0, 2) If IsNumeric(A) Then Else Exit Sub End If If B.Value = "" Then B.Value = A.Value If C.Value = "" Then C.Value = A.Value If A.Value > B.Value Then B.Value = A.Value If A.Value < C.Value Then C.Value = A.Value Next i End Sub とすると数値以外の行の時点で停止してしまいます。 その行を飛ばして次の行に進むにはどうしたらいいのでしょうか?

  • エクセルのマクロで複数セル指定は?

    以前(7月22日 質問No.936181)の質問でご回答を頂いたマクロなんですが、 Private Sub Worksheet_Change(ByVal Target As Range) Dim MyData As String Dim i As Integer Dim ImaNanji As String Dim SakkiNanji As String Dim ImaNanpun As String Dim SakkiNanpun As String SakkiNanpun = Cells(2, 3).Value ImaNanji = Cells(1, 3).Value ImaNanpun = Mid(ImaNanji, Len(ImaNanji) - 4, 2) If ImaNanpun <> SakkiNanpun Then Application.EnableEvents = False For i = 10 To 2 Step -1 MyData = Cells(i - 1, 2).Value Cells(i, 2).Value = MyData Next i MyData = Cells(1, 1).Value Cells(1, 2).Value = MyData Cells(2, 3).Value = ImaNanpun Application.EnableEvents = True End If End Sub A1のデータをB1からB10に一分おきにつぎつぎに書き込むというものなんですが、ひとつのセルではなく複数のセル(例えばA1からA30の30個のセル)をいっぺんに書き込むようにしたいのですが可能でしょうか? よろしくお願いします。

  • Excel VBAで文字列の部分一致の文字列を表示

    以前、こちらで頭5文字までの一致で文字列を表示するVBAを教えて頂きました。今回はFINDなどの部分一致での文字列を表示することをしたいのですが、ご教示いただけますと幸いです。 下記はSheet1のA3に文字を5文字以内いれるとSheet2のC列からピックアップしてSheet1のA列に文字列を表示する及びSheet2のB列のデータをSheet1のC列に表示させるVBAです。 Sub Test2() Dim Ws1 As Worksheet, Ws2 As Worksheet Dim SData As String, i As Long, VRet As Variant Dim c As Range, LastRow As Long Set Ws1 = Sheets("Sheet1") Set Ws2 = Sheets("Sheet2") SData = CStr(Ws1.Range("A3").Value) If SData = "" Then Exit Sub i = 5 LastRow = Ws1.Cells(Rows.Count, "A").End(xlUp).Row If LastRow < i Then LastRow = i End If Ws1.Range(Ws1.Cells(i, "A"), Ws1.Cells(LastRow, "C")).ClearContents With Ws2 For Each c In .Range(.Cells(1, "C"), .Cells(Rows.Count, "C").End(xlUp)) VRet = InStr(1, CStr(c.Value), SData, vbTextCompare) If VRet = 1 And Len(c.Value) >= 10 Then Ws1.Cells(i, "A").Resize(1, 2).Value = c.Resize(1, 2).Value 'とりあえずSheet2のB列のデータ(C列のデータに同期したデータ)をSheet1のC列に Ws1.Cells(i, "C").Value = .Cells(c.Row, "B").Value i = i + 1 End If Next End With End Sub 宜しくお願い致します。

  • Excel VBA ・・・教えてください

    何度も質問させて頂いてます。すみません、 下記のプログラムはこの場で教えて頂いたプログラムで、 実行すると●の後を▲や■が追いかける動きをします。 下記のプログラムをある程度使用して 1~20の数字が順々で追いかけっこする プログラムを作成するにはどのようにすればいいのでしょうか… できればプログラムは長めにならず 20の数字から簡単に増やすことのできるような そんなプログラムが作成したいです… どなたかアドバイスお持ちの方 教えて下さいお願いします... Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim X1 As Integer, Y1 As Integer Dim X2 As Integer, Y2 As Integer Dim maru As String, yoko As String, tate As String Dim sankaku As String, shikaku As String Sub 描画() Cells(Y2, X2).Value = shikaku Cells(Y1, X1).Value = sankaku Cells(Y, X).Value = maru End Sub Sub 削除() Cells(Y2, X2).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() X2 = X1 Y2 = Y1 X1 = X Y1 = Y If yoko = "右" Then X = X + 1 Else X = X - 1 End If If X = 30 Then yoko = "左" ElseIf X = 1 Then yoko = "右" End If If tate = "上" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 20 Then tate = "下" ElseIf Y = 1 Then tate = "上" End If End Sub Sub main() maru = "●" sankaku = "▲" shikaku = "■" X = 1 Y = 1 X1 = 1 Y1 = 1 X2 = 1 Y2 = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub

  • エクセル VBAについて

    はじめて質問するのですが(閲覧もほとんどしていませんでした)、 ネチケット違反等がありましたら申し訳ありません。 エクセルVBAで下記のようなことをしたいのですが、 できずに困っています。 A列で文字が入っているセルを、上から下まで確認し、 『在庫』という文字が入ってるセルの下2行に空白行を入れたく 思っています。 とりあえず自分で作ってみたのは、 ******************** Sub 行挿入() Dim i As Integer Dim a As String For i = 1 To 1000 Cells(1, i).Value = a If a = "在庫" Then Rows(i + 1).Insert Rows(i + 2).Insert Else End If Next i End Sub ************************************ 初心者で申し訳ないのですが、上記を実行すると、 アプリケーション定義&オブジェクト定義というエラーが出ます。 何がいけないのでしょうか? 恐れ入りますが、教えてください。 よろしくお願い致します。

専門家に質問してみよう