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

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



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

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


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

数式の関数の使用回数、関数名を配列で返す|エクセル雑感(10月19日)
Rangeオブジェクトを受け取り"行数,列数"で埋める|エクセル雑感(10月16日)
数値変数の値を別の変数を使わずに入れ替える|エクセル雑感(10月13日)
WEBスクレイピング(selenium)|Python入門(10月11日)
エクセルを操作する(pywin32:win32com)|Python入門(10月5日)
エクセルを操作する(openpyxl)|Python入門(10月3日)
pipコマンド(外部ライブラリのインストール)|Python入門(10月1日)
CSV読み書き(csvモジュール)|Python入門(9月29日)
「Excel 4.0 マクロ」の使い方|VBA技術解説(9月28日)
CSV読み込みとopen()関数とwith文|Python入門(9月28日)


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

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




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


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



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