ツイッターで出されたVBAのお題(悪魔のCSV)をやってみた
ツイッターで出題されたVBAの問題をやってみました。
ツイッターのエクセルおよびVBA関係の人達の間では、いろいろと面白く勉強になる問題を出し合うという事が行われています。
フォローして参加してみると楽しいと思いますよ。
VBAお題の関連ツイート
博多親不孝通りミッドナイト 悪魔のCSV
「VBAによる解析シリーズその2 カッコ」をやってみた
せっかくなので、ここに記録として残しておきます。
VBA問題の概要
名前,数量,単価,金額,メモ
フライパン,2,1,020,2,040,このフライパンは1,020円にしては高性能!
これはつまり、本来なら少なくともカンマを含む項目部分は"ダブルクォーテーションで囲われているべきものです。
名前,数量,単価,金額,メモ
フライパン,2,"1,020","2,040","このフライパンは1,020円にしては高性能!"
最低でもこのようになっているべきデータです。
だって、CSVなのですから、カンマくぎりなのですから。
つまり、この元のCSV?をちゃんと人間が判断するように読める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
Stopの時点で、ローカルウインドウ等で、変数rtnの中を確認してください。
シートに出力しても良いですが、4つだけなのでローカルウインドウで十分でしょう。
作成時間はちゃんと測ってないし、途中で別の事したりなのではっきりしませんが、
たぶん1時間くらいだと思います。
途中でツイッターやったりしてたので、大体これくらいじゃないかなーという程度の時間です。
もっと効率のよい、より良いVBAができるはずです。
どのようなアルゴリズムをどのようにVBA実装すればよいか・・・
そのあたりについては先の出題ページに順次掲載されると思いますので、見てみると良いでしょう。
一度腕試しでチャレンジしてみるのも良いと思います。
同じテーマ「ツイッター出題回答 」の記事
「VBAによる解析シリーズその2 カッコ」をやってみた
ツイッターで出されたVBAのお題(悪魔のCSV)をやってみた
「VBAで導関数を求めよ」ツイッターのお題をやってみた
ツイッターのお題「君の名は?」
ツイッターのお題「CSV編集」
アルファベットの26進(ツイッターお題)
ナンバープレート数字遊び:ツイッターお題
サロゲートペアに対応した自作関数(Len,Left,Mid,Right)
迷路にネコが挑戦したら、どうなるかな…
迷路ネコが影分身の術を体得したら…
新着記事NEW ・・・新着記事一覧を見る
新旧マスタの差異比較|Power Query(M言語)入門(2023-02-28)
有効な最新単価の取得|Power Query(M言語)入門(2023-02-26)
有効な最新単価の取得|Power Query(M言語)入門(2023-02-21)
グルーブ内の最小・最大|Power Query(M言語)入門(2023-02-17)
2つのテーブルのマージ|Power Query(M言語)入門(2023-02-15)
「売上」が数値の行のみ取り込む|Power Query(M言語)入門(2023-02-13)
A列のヘッダー名を変更する|Power Query(M言語)入門(2023-02-11)
CSVのA列が日付の行だけを取り込む|Power Query(M言語)入門(2023-02-10)
列数不定のCSVの取り込み|Power Query(M言語)入門(2023-02-09)
別ブックの最終シートの取り込み|Power Query(M言語)入門(2023-02-08)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.マクロって何?VBAって何?|VBA入門
7.並べ替え(Sort)|VBA入門
8.Excelショートカットキー一覧|Excelリファレンス
9.エクセルVBAでのシート指定方法|VBA技術解説
10.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。