以下は
[[20050415103520]]『マクロについて』(まりお)
についての考察です。
【命題】
以下のデータをフィルタオプションの抽出対象として扱う
C05-001
C05-001A
C05-001,002
C05-001〜003
データ形態としては以下のようにまとめられる。
(nは任意の半角数字、?は任意の半角アルファベット)
?nn-nnn?
?nn-nnn?,nnn?
?nn-nnn?〜nnn?
【所見】
まず、上記の形のデータはデータベースの検索対象の値としては非常に扱いにくいということがいえます。
【その理由】
"C05-001〜003"という文字列を見て、人間は"C05-001","C05-002","C05-003"であると
「推測」できますが、コンピューターの場合は書いてないことを「推測」する能力はありません。
人間の脳みそは不足した(欠落した)データを経験でかなりの部分を補完できますが、
コンピューターは与えられたもの以上のことは(今のところ)出来ません。
【解決への考察】
フィルタオプションでのデータの抽出、検索が最終的な目的であれば、
最初から扱いやすいデータフォーマットでリストを作成するのが最良です。
つまり、
?nn-nnn?〜nnn?
という書き方ではなく、
?nn-nnn?,nnn?,nnn?,nnn?,・・・・
という書き方に統一されていれば、幾分か検索しやすいデータと言えます。
例えば、プログラムとして検索しやすいデータベースとすることを目的として
「"C05-001〜003"と書かれていたら、"C05-001","C05-002","C05-003"であると判断しなさい」
ということを「判断」する、もしくは、欠落したデータを補うような仕組みを作ったり、
"C05-001〜003"と言う記述の他に、"C05-001"から、"C05-003"までに関連したレコードですよ、
ということを示すデータを同じ行へ追加してやるということは可能です。
が、あるデータについて、
>−でくくる会社や、","と"〜"をまぜて表示する会社もあります。
これが一番厄介です。人間が認識可能な記述をそのままパソコンの世界へ反映すると、
それを解釈するパソコンの側では入力者の意図を推測し、それを反映するためのプログラムを
誰かが作ってやらねばなりません。
が、入力者が適当に解釈して入力するであろうあらゆるパターンを事前に予想して
プログラミングすることは(私には)かなり至難です。
【解決案】
下記の複合により抽出前に扱いやすいデータにしておく。
(1)入力に関するルールを取り決める
人間が入力する限り、徹底は無理ですが、扱いやすいデータとするためには入力の
ルールは必要です。入力する側へ協力をお願いする必要はあるかもしれません。
(2)入力の時点でイレギュラーな入力を制限する
もとのデータがどのように作成されているかが、不明ですが、
もし、Excelでの入力がもとになっているのであれば、例えば入力規則などを使って
入力する値に制限をかけることが出来ます。
例えば、日本語入力機能を無効にするだけで全角文字での入力を制限することが出来ますし、
入力時メッセージでデータ入力のルールを表示することも可能です。
ただ、Excel以外のアプリケーションから取得されたデータであるならば、この方法は厳しい鴨。
(3)想定できるケースをVBA上で処理して、イレギュラーなデータは「人間が判断して」データに修正を加える。
"C05-001〜003"という文字列をVBAで"〜"があるデータ範囲を示す文字列であると想定しておいて、
そのレコードが"C05-"に関する"001","002","003"のことであるという情報を付け加えることは出来ます。
が、想定外の文字列が使用されている場合はこうした処理はお手上げになるので、
イレギュラーなデータを見つけ出してユーザーに訂正を促す、というのは商用アプリケーションでも
よく見かける手法です。
【方針】
入力の部分はどうなっているかわからないので、とりあえす、該当ファイルでの処理のみ検討します。
「工事番号」をデータベースとして扱いやすいものとするために整形し、そのためのデータフィールドを追加。
コンボボックスで「会社記号&年度」部分と「番号」部分の検索を容易にするためのデータベースも整備する。
「工事番号」が整形できないようなデータの場合はユーザーへ修正を促す仕組みを盛り込んでおく。
【試作】
選択セルに下記の形式のデータが入力されていた場合にその右隣2列へ検索用データを作成するマクロ。
?nn-nnn? →?nn nnn?
?nn-nnn?,nnn? →?nn nnn?,nnn?
?nn-nnn?〜nnn? →?nn nnn?,nnn,nnn,nnn,・・・・,nnn?
開発のための試作品につき、重要なデータでは試さないようにしてください。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sub test()
Dim MyStr As String
Dim MyVar As Variant
MyStr = Selection.Value
Selection.Cells(1, 2).Value = Left(MyStr, 3)
MyStr = Mid(MyStr, 5)
If Len(WorksheetFunction.Substitute(MyStr, ",", "")) <> Len(MyStr) Then
With Selection.Cells(1, 3)
.NumberFormatLocal = "@"
.Value = MyStr
End With
ElseIf Len(WorksheetFunction.Substitute(MyStr, "〜", "")) <> Len(MyStr) Then
MyVar = Split(MyStr, "〜")
MyStr = MyVar(0)
If MyVar(1) = "" Then MyVar(1) = "0"
Do While Left(MyVar(1), 3) - Left(MyVar(0), 3) > 0
MyStr = MyStr & "," & Format(Left(MyVar(0), 3) + 1, "000")
MyVar(0) = Format(Left(MyVar(0), 3) + 1, "000")
Loop
With Selection.Cells(1, 3)
.NumberFormatLocal = "@"
.Value = MyStr
End With
Else
Selection.Cells(1, 3).Value = "規定外の入力"
End If
End Sub