エクセル雑感
ツイッターで出された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実装すればよいか・・・
そのあたりについては先の出題ページに順次掲載されると思いますので、見てみると良いでしょう。

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



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

エクセル関連ツイートNo2
エクセル関連ツイートNo3
エクセル関連ツイートNo4
エクセル関連ツイートNo5
ツイッターで出されたVBAのお題をやってみた
「VBAによる解析シリーズその2 カッコ」をやってみた
ツイッターのお題「CSV編集」
文字列のセルだけ結合(ツイッターのお題)
時間に関する関数の扱い方(ツイッター投稿)
アルファベットの26進(ツイッターお題)
COUNTIF関数の結果は?(ツイッターお題)


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

COUNTIF関数の結果は?(ツイッターお題)|エクセル雑感(5月30日)
エクセル&VBA オンライン講座|エクセル セミナー(5月29日)
アルファベットの26進(ツイッターお題)|エクセル雑感(5月19日)
VBAが消えてしまった!マクロが壊れて動かない!|エクセル雑感(5月8日)
時間に関する関数の扱い方(ツイッター投稿)|エクセル雑感(5月6日)
文字列のセルだけ結合(ツイッターのお題)|エクセル雑感(5月5日)
表示形式.言語設定|エクセル入門(5月1日)
GoogleスプレッドシートをExcelにインポートする|VBAサンプル集(4月28日)
ツイッターのお題「CSV編集」|エクセル雑感(4月25日)
プログレスバーを自作する|ユーザーフォーム入門(4月18日)


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

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




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


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



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