エクセル雑感
ツイッターで出されたVBAのお題をやってみた

ExcelマクロVBAとエクセル関数についての私的雑感
最終更新日:2020-01-13

ツイッターで出されたVBAのお題をやってみた


ツイッターで出題されたVBAの問題をやってみました。
ツイッターのエクセルおよびVBA関係の人達の間では、いろいろと面白く勉強になる問題を出し合うという事が行われています。
フォローして参加してみると楽しいと思いますよ。


もとネタはこちら、
VBAお題の関連ツイート

VBAのお題のページ(仕様詳細)はこちら
博多親不孝通りミッドナイト 悪魔のCSV

以前にも出題された方と同じ方からの出題です。
「VBAによる解析シリーズその2 カッコ」をやってみた
ツイッターで出たVBAのお題をやってみました。もとネタはこちら、VBAによる解析シリーズその2カッコ 関連ツイート なかなか楽しかったので、VBAコードを掲載しておきます。まず最初にお題から受ける印象は、再帰処理を行うという事になると思います。

せっかくなので、ここに記録として残しておきます。

VBA問題の概要

一言で言うと、CSVと言う名のメチャクチャなテキストデータをCSVのつもりで処理できるようにするという事です。

名前,数量,単価,金額,メモ
フライパン,2,1,020,2,040,このフライパンは1,020円にしては高性能!
これは、CSVなのか・・・
これはつまり、本来なら少なくともカンマを含む項目部分は"ダブルクォーテーションで囲われているべきものです。

名前,数量,単価,金額,メモ
フライパン,2,"1,020","2,040","このフライパンは1,020円にしては高性能!"

最低でもこのようになっているべきデータです。
だって、CSVなのですから、カンマくぎりなのですから。
つまり、この元のCSV?をちゃんと人間が判断するように読めるVBAを作るという事です。

作成すべきVBAのお題としては、
VBAの関数(Function)を作成して、各項目の先頭文字位置を配列で返す。
{7,9,15,21}
これを返すFunctionを作れというものです。
区切り位置の判断基準としては、

「数量項目*単価項目=合計金額」この条件を満たすカンマ位置という事です。
詳細については、先のページを参照してください。

VBAコード

Function akuma_no_csv(a_line)
  Dim rtn(3) As Long
  Dim re As New RegExp
  Dim mc As MatchCollection
  
  re.Global = False
  re.Pattern = ",\d"
  rtn(0) = re.Execute(a_line)(0).FirstIndex + 2
  re.Pattern = "\d,\D"
  rtn(3) = re.Execute(a_line)(0).FirstIndex + 3
  
  Dim ary
  ary = Split(Mid(a_line, rtn(0), rtn(3) - rtn(0) - 1), ",")
  
  Dim num1, num2, num3
  Dim i, i1, i2, i3, flgOk
  For i1 = LBound(ary) To UBound(ary) - 2
    For i2 = i1 + 1 To UBound(ary) - 1
      For i3 = i2 + 1 To UBound(ary)
        num1 = "": num2 = "": num3 = ""
        For i = i1 To i2 - 1
          num1 = num1 & ary(i)
        Next
        For i = i2 To i3 - 1
          num2 = num2 & ary(i)
        Next
        For i = i3 To UBound(ary)
          num3 = num3 & ary(i)
        Next
        flgOk = isOk(num1, num2, num3)
        If flgOk Then
          rtn(1) = rtn(0) + getIndex(ary, i2)
          rtn(2) = rtn(0) + getIndex(ary, i3)
          Exit For
        End If
      Next
      If flgOk Then Exit For
    Next
    If flgOk Then Exit For
  Next
  
  If Not flgOk Then
    rtn(0) = 0: rtn(3) = 0
  End If
  akuma_no_csv = rtn
End Function

Function isOk(num1, num2, num3) As Boolean
  isOk = False
  If Not IsNumeric(num1 & num2 & num3) Then Exit Function
  If CLng(num3) = num1 * num2 Then
    isOk = True
  End If
End Function

Function getIndex(ary, ix) As Long
  Dim i As Long
  For i = LBound(ary) To ix - 1
    getIndex = getIndex + Len(ary(i)) + 1
  Next
End Function

使い方および説明



Sub test()
  Dim str As String
  str = "フライパン,2,1,020,2,040,このフライパンは1,020円にしては高性能!"
  Dim rtn
  rtn = akuma_no_csv(str)
  Stop
End Sub

とからせの時点で、ローカルウインドウ等で、変数rtnの中を確認してください。
シートに出力しても良いですが、4つだけなのでローカルウインドウで十分でしょう。

ツイッターのお題に対する回答なので、VBA解説は抜きにします。

かなり即興で作りました。
作成時間はちゃんと測ってないし、途中で別の事したりなのではっきりしませんが、
たぶん1時間くらいだと思います。
途中でツイッターやったりしてたので、大体これくらいじゃないかなーという程度の時間です。

上記VBAはツイッターで速攻解答したコードをそのまま載せています。
もっと効率のよい、より良いVBAができるはずです。
どのようなアルゴリズムをどのようにVBA実装すればよいか・・・
そのあたりについては先の出題ページに順次掲載されると思いますので、見てみると良いでしょう。

文字列処理としては面白いお題だと思いますので、
一度腕試しでチャレンジしてみるのも良いと思います。



同じテーマ「エクセル雑感」の記事

エクセル関連ツイートNo4
エクセル関連ツイートNo5
「VBAによる解析シリーズその2 カッコ」をやってみた
ツイッターで出されたVBAのお題をやってみた
「VBAで導関数を求めよ」ツイッターのお題をやってみた
ツイッターのお題「君の名は?」
ツイッターのお題「CSV編集」
アルファベットの26進(ツイッターお題)
保護されたブックの非表示シートについて
文字列のセルだけ結合
時間に関する関数の扱い方


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

多階層フォルダ(ディレクトリ)の作成|VBAサンプル集(7月31日)
VBAのインデントについて|VBA技術解説(7月16日)
「VBA Match関数の限界」についての誤解|エクセル雑感(7月15日)
省略可能なVariant引数の参照不可をラップ関数で利用|VBA技術解説(7月12日)
100桁の正の整数値の足し算|エクセル雑感(7月9日)
LSetとユーザー定義型のコピー(100桁の足し算)|VBA技術解説(7月9日)
Variant仮引数のByRefとByValの挙動違い|エクセル雑感(7月5日)
Variant仮引数にRange.Valueを配列で渡す方法|エクセル雑感(7月5日)
Variantの数値型と文字列型の比較|エクセル雑感(7月1日)
VBAのVariant型について|VBA技術解説(6月30日)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.マクロって何?VBAって何?|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
8.セルに文字を入れるとは(Range,Value)|VBA入門
9.とにかく書いてみよう(Sub,End Sub)|VBA入門
10.マクロはどこに書くの(VBEの起動)|VBA入門




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


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



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