VBA練習問題
VBA100本ノック 58本目:番号リストを簡潔にした文字列で返す

VBAを100本の練習問題で鍛えます
公開日:2020-12-30 最終更新日:2021-01-13

VBA100本ノック 58本目:番号リストを簡潔にした文字列で返す


配列と数値nを受け取り、配列の番号リストを簡潔にした文字列で返す問題です。


ツイッター連動企画です。
ツイートでの見やすさを考慮して、ブック・シート指定等を適宜省略しています。

VBAテスト用のサンプルデータはご自身でご用意ください。


出題

出題ツイートへのリンク

#VBA100本ノック 58本目
配列と数値nを受け取り、配列の番号リストを簡潔にした文字列で返すFunctionを作成します。
n連続以上の場合は「開始-終了」に変換した上でカンマ区切りで結合。
配列={1,2,3,5,8,9,11,12,13,14,15,17,19,20,21,22}
n=2→"1-3,5,8-9,11-15,17,19-22"
※結果は画像を参考に

マクロ VBA 100本ノック


VBA作成タイム

この下に頂いた回答へのリンクと解説を掲載しています。
途中まででも良いので、できるだけ自分でVBAを書いてみましょう。


他の人の回答および解説を見て、書いたVBAを見直してみましょう。


頂いた回答

解説

連続している数値だけの配列を作成し、途切れたら次の配列を作成します。
この配列を順次配列に入れジャグ配列を作成しています。
その後に、ジャグ配列から指定数値以上の連続かどうかで出力文字の作成方法を変えながら戻り値を作成しています。

Function VBA100_58_01(ByRef ary, ByVal n As Long) As String
  If Not IsArray(ary) Then Exit Function
  If UBound(ary) < 0 Then Exit Function
  
  Dim jagAry, tmpAry
  Dim i As Long, ix As Long
  
  ReDim jagAry(ix)
  jagAry(ix) = Array(ary(LBound(ary)))
  For i = LBound(ary) + 1 To UBound(ary)
    If ary(i) = jagAry(ix)(UBound(jagAry(ix))) + 1 Then
      tmpAry = jagAry(ix)
      ReDim Preserve tmpAry(UBound(tmpAry) + 1)
      tmpAry(UBound(tmpAry)) = ary(i)
      jagAry(ix) = tmpAry
    Else
      ix = ix + 1
      ReDim Preserve jagAry(ix)
      jagAry(ix) = Array(ary(i))
    End If
  Next
  
  For i = LBound(jagAry) To UBound(jagAry)
    Select Case UBound(jagAry(i))
      Case Is < n - 1
        jagAry(i) = Join(jagAry(i), ",")
      Case Else
        jagAry(i) = jagAry(i)(LBound(jagAry(i))) & "-" & jagAry(i)(UBound(jagAry(i)))
    End Select
  Next
  
  VBA100_58_01 = Join(jagAry)
End Function

マクロ VBA 100本ノック


このVBAでは途中経過が分かり易いようにジャグ配列にしていますが、連続が途切れた都度に文字列出力しても良いものです。
都度出力するVBAは記事補足に掲載しました。


補足

以下のVBAでは、連続している数値だけの配列を作成し、
連続が途切れた時、指定連続以上か未満かで出力文字列を変更しています。
・指定以上の連続数値なら「開始-終了」で出力
・指定未満ならカンマ区切りで出力

Function VBA100_58_02(ByRef ary, ByVal n As Long) As String
  If Not IsArray(ary) Then Exit Function
  If UBound(ary) < 0 Then Exit Function
  
  Dim rtn As String, tmpAry As Variant
  Dim i As Long
  
  ReDim tmpAry(0): tmpAry(0) = ary(LBound(ary))
  For i = LBound(ary) + 1 To UBound(ary)
    If ary(i) = ary(i - 1) + 1 Then
      ReDim Preserve tmpAry(UBound(tmpAry) + 1)
      tmpAry(UBound(tmpAry)) = ary(i)
    Else
      Call Array2String(rtn, tmpAry, n)
      ReDim tmpAry(0)
      tmpAry(UBound(tmpAry)) = ary(i)
    End If
  Next
  Call Array2String(rtn, tmpAry, n)
  
  VBA100_58_02 = rtn
End Function

Function Array2String(ByRef aRtn As String, ByRef aAry, ByVal n As Long)
  If aRtn <> "" Then aRtn = aRtn & ","
  If UBound(aAry) < n - 1 Then
    aRtn = aRtn & Join(aAry, ",")
  Else
    aRtn = aRtn & aAry(LBound(aAry)) & "-" & aAry(UBound(aAry))
  End If
End Function


サイト内関連ページ

第106回.Functionプロシージャー
プログラム(マクロVBA)内で特定の処理を実行し値を返すプロシージャーです。これはつまり、Functionプロシージャーで独自の関数をつくれるということです。Subプロシージャーとの違いは、値を返すか返さないかの違いです。
第107回.プロシージャーの引数
・引数の構文 ・引数の使用例 ・引数について




同じテーマ「VBA100本ノック」の記事

55本目:他ブックのマクロを起動
56本目:数式内の自身のシート名を消す
57本目:ファイルの更新日時
58本目:番号リストを簡潔にした文字列で返す
59本目:12ヶ月分のシートを四半期で分割
60本目:「株式会社」の表記ゆれ置換
61本目:「ふりがな」の取得と設定
62本目:独自のZLOOKUP関数を作成
63本目:複数シートの連結
64本目:リンクされた図(カメラ機能)
65本目:固定長テキスト出力


新着記事NEW ・・・新着記事一覧を見る

AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ