• ベストアンサー

VBA、Excel、文字列の置換について

エクセルのVBAを勉強しているものなのですが 行き詰ってしまったので有識者の方、アドバイスをお願いします 目的:セルに入力されているカンマで区切られた文字列(例、1,2,5,6,7,8,10,11・・・)で連番の場合間の数字を"-"で省略(例、1,2,5-8,10,11・・・)する関数の作成 以下、プログラム (1)カンマで区切られた文字列をスプリットし、配列化 For Each cl In moji myData = Split(cl, ",") Next (2)3つ以上の連番の場合、"-"で文字列の短縮化 For l = 1 To UBound(myData) If myData(l) = myData(l + 1) - 1 Then If myData(l) = myData(l - 1) + 1 Then myData(l) = "-" ElseIf myData(l) = "-" Then myData(l) = "" Else myData(l) = myData(l) & "," End If Else myData(l) = myData(l) & "," End If Next l (3)配列をカンマで区切られた文字列として出力 For m = 0 To UBound(myData) bunkai = bunkai & myData(m) Next m

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

  • ベストアンサー
  • hotosys
  • ベストアンサー率67% (97/143)
回答No.4

こんなのはどうでしょうか? 連続でなく3連続で省略する場合です。(1,2は省略せず、1,2,3は1-3に省略します。) 配列のデータのあるデータに着目すると、-になるのは自分の前後が連番の場合になると思います。 例えば2,3,4で、3に着目している場合などです。 最初と最後は-になる事は無いのでそのまま出力して、2番目から最後から2番目までをチェックします。 まず、基本的な考え方です。 Sub sample1() Dim cl As String '元文字列 Dim dst As String '結果文字列 Dim myData() As String Dim l As Integer cl = "1,3,5,6,7,8,9,10,11,13,14,15" myData = Split(cl, ",") dst = myData(0) & "," '最初はそのまま For l = 1 To UBound(myData) - 1 If (myData(l) - myData(l - 1) = 1) And (myData(l + 1) - myData(l) = 1) Then '前後が連続なら dst = dst & "-," '- Else dst = dst & myData(l) & "," '前後が連続でない場合はそのまま End If Next dst = dst & myData(UBound(myData)) '最後はそのまま MsgBox dst End Sub ただし、このままでは連続が複数あると-,-,になってしまうのと、-の前後のカンマは不要なので、若干変更します。 Sub sample2() Dim cl As String '元文字列 Dim dst As String '結果文字列 Dim myData() As String Dim l As Integer cl = "1,3,5,6,7,8,9,10,11,13,14,15" myData = Split(cl, ",") dst = myData(0) & "," '最初はそのまま For l = 1 To UBound(myData) - 1 If (myData(l) - myData(l - 1) = 1) And (myData(l + 1) - myData(l) = 1) Then '前後が連続なら If Right(dst, 2) <> "-," Then '前が-でなければ(連続-にならないように) dst = dst & "-," '- End If Else dst = dst & myData(l) & "," '前後が連続でない場合はそのまま End If Next dst = dst & myData(UBound(myData)) '最後はそのまま dst = Replace(dst, ",-,", "-") ',-,を-だけにする MsgBox dst End Sub p.s. No.2さんへ 最後が連続してる場合(flag=trueでnext lを終えた場合)にチェックが必要ではないでしょうか Next l If flag = True Then bunkai = bunkai & "-" & myData(UBound(myData)) End If

sak1982515
質問者

お礼

回答ありがとうございます 三連続の場合の処理を苦しんでいたのですが解決しました シンプルですばらしいですね!

その他の回答 (3)

  • okormazd
  • ベストアンサー率50% (1224/2412)
回答No.3

やっつけ仕事 Sub test() mojiretu = Selection.Value '適当な文字列を指定してください moji = Split(mojiretu, ",") l = UBound(moji) For i = 0 To l - 1 moji(i) = moji(i) & "," 'あらかじめ","をつけてしまう Next i0 = 0 i = 0 Do While i < l - 1 While Val(moji(i)) + 1 = Val(moji(i + 1)) '連続しているかどうか調べる i = i + 1 Wend f = i - i0 '連続している個数 If f = 0 Then i = i + 1 End If i0 = i If f > 2 Then '6-9などの処理 j = i - f moji(j - 1) = Left(moji(j - 1), Len(moji(j - 1)) - 1) 'おしりの","をはずす moji(j) = "-" j = j + 1 While j < i moji(j) = "" '連続しているところは文字数0 j = j + 1 Wend End If Loop For i = 0 To l '組み立て mojiretu2 = mojiretu2 & moji(i) Next End Sub

sak1982515
質問者

お礼

回答ありがとうございます Val関数を使えばカンマが加わった配列でもif文が使えますね 勉強になりました ありがとうございま

  • bkbkb
  • ベストアンサー率33% (97/289)
回答No.2

動くか確かめてませんが For Each cl In moji myData = Split(cl, ",") temp = myData(0) bunkai = myData(0) flag = false For l = 1 To UBound(myData) If myData(l) = temp + 1 Then flag=true '連続しているよの印をつける Else if flag = true then '今まで連続していたら bunkai = bunkai & "-" & myData(l-1) & "," & myData(l) else '連続していなかったら bunkai = bunkai & "," & myData(l) end if flag = false '次に備えて End If temp = myData(l) Next l Next こんなんで多分動作するんじゃないでしょうか。 あんまりスマートじゃないですが…

sak1982515
質問者

お礼

素早い回答ありがとうございます なるほど、連続しているかしていないかの印をつけると分かりやすいですね 上記のプログラムを参考に勉強させていただきます

  • bkbkb
  • ベストアンサー率33% (97/289)
回答No.1

まず、一つ For Each cl In moji    myData = Split(cl, ",") Next myDataは配列になっていないので、この処理はダメですよ。 最後の行のデータしか結果が出ないでしょう myDataを配列にするか、このループの中に処理を入れてください。 If myData(l) = myData(l - 1) + 1 Then myDataは-や,を付けたりする処理を行っているので、myData(l - 1)は数字でない可能性があります。そこに1を足しても思った結果にはならないでしょう(-に1を足して-1になったりしますよ) それと、配列は0から始まります。 1からだとデータが足りなくなりますよ。 これを動くように書きなおすと、結構な変更になりますね…

関連するQ&A