ツイッターで出された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で導関数を求めよ」ツイッターのお題をやってみた
新着記事NEW ・・・新着記事一覧を見る
TRIMRANGE関数(セル範囲をトリム:端の空白セルを除外)|エクセル入門(2024-08-30)
正規表現関数(REGEXTEST,REGEXREPLACE,REGEXEXTRACT)|エクセル入門(2024-07-02)
エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.変数宣言のDimとデータ型|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.メッセージボックス(MsgBox関数)|VBA入門
8.セルのクリア(Clear,ClearContents)|VBA入門
9.ブック・シートの選択(Select,Activate)|VBA入門
10.条件分岐(Select Case)|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。