Access (一般機能)

Accessの一般機能に関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : Access 2016)
文字の取り出し関数について
投稿日時: 21/03/08 13:45:19
投稿者: あのこ

お世話になります。
関数についてお伺いします。
 
あるフィールド1に文字の羅列が入っており、
【A】あいうえお【B】いうえ【C】かきく
のように文章が入力されています。
ご教示いただきたいのは
【A】から後ろの次の【までの文章の取り出しをしたいです。
この例ですと答えは「あいうえお」となりますが、
【A】の後は【B】の場合も【C】の場合もあります。
関数組み合わせ等やってみましたが上手くいきません。
ご教示いただければ助かります。よろしくお願いします。

回答
投稿日時: 21/03/09 18:15:27
投稿者: Suzu

最初の「あいうえお」 だけであれば、
・Mid関数
・InStr関数
で対処できるでしょう。
 
でも、【?】の数が不定であったり、【?】と次の【?】の間 の 文字数 が違い
【?】の 2セット目以降も 作業列を使用せずにクエリ式で取得したいとなると、かなり面倒ですね。
 
 
・作業列を用意するか
・VBAを使用するか
 
が良いと思います。

回答
投稿日時: 21/03/10 09:12:42
投稿者: Suzu

VBA を使う例です。
 
標準モジュール
-------------------------------------------------------------------------
Function getString(varValue As Variant, cnt As Long) As String
    'VBScript_RegExp_55.RegExp
    Dim Reg As Object
    Dim strValue As String
    Dim varValues As Variant
 
    Set Reg = CreateObject("VBScript.RegExp")
 
    If Len(varValue) = 0 Then Exit Function
 
    With Reg
        .Pattern = "【\w】"
        .IgnoreCase = True
        .Global = True
        varValue = Reg.Replace(varValue, vbCrLf)
    End With
 
    If Left(strValue, 1) = vbCrLf Then strValue = Mid(strValue, 2)
 
    varValues = Split(varValue, vbCrLf)
    If UBound(varValues) >= cnt Then getString = varValues(cnt)
End Function
-------------------------------------------------------------------------
 
クエリSQL
-------------------------------------------------------------------------
SELECT
  *,
  getString([フィールド名],1) AS F1,
  getString([フィールド名],2) AS F2,
  getString([フィールド名],3) AS F3,
  getString([フィールド名],4) AS F4,
  getString([フィールド名],5) AS F5,
   :
FROM テーブル名
-------------------------------------------------------------------------
 
正規表現を使い、【x】(xは任意の一文字)を検知し、【x】を 改行コードに置換
更に、改行コードをキーに配列に入れ、配列の n番目を返しています。
 
各フィールドの関数毎に、いちいち配列を作って、引数によって配列の n番目の値を返しています。
なので、1レコード 当り getString([フィールド名],〜) AS F〜 の回数だけ 同じ配列を作っています。
1レコード で 同じ配列を作っているので 配列部分は、共通化できると思うのですが・・
手抜きで、こんなコードになっています。
 
ですので、処理速度は期待しないでください。

投稿日時: 21/03/10 20:59:07
投稿者: あのこ

ありがとうございます😭
VB AのPattern = "【\w】の【\w】の
カッコの中には、中カッコの中名を入れるのでしょうか??
 
あとSQLの getString([フィールド名],1) AS F1,の
1とF1は何を意味しているのでしょうか?
質問ばかりで申し訳ありません。

回答
投稿日時: 21/03/12 09:31:44
投稿者: Suzu

引用:
Pattern = "【\w】の【\w】の
カッコの中には、中カッコの中名を入れるのでしょうか??

 
これは、
引用:
正規表現を使い、【x】(xは任意の一文字)を検知し、【x】を 改行コードに置換
になります。
 
エクセルの神髄
VBAで正規表現を利用する(RegExp)
https://excel-ubara.com/excelvba4/EXCEL232.html
 
「【」と「】」に囲まれた任意の一文字を探し、改行コードに置換しているのです。
 
 
引用:
あとSQLの getString([フィールド名],1) AS F1,の
1とF1は何を意味しているのでしょうか?

 
getString では、
  引数 [フィールド名] に指定したフィールドのデータを要素毎に分け、
  引数 1 は、その要素のうちの 1番目の要素 を返す
になります。
 
そのフィールドのデータが
『【A】あいうえお【B】いうえ【C】かきく』の場合、
 
要素 1 : あいうえお
要素 2 : いうえ
要素 3 : かきく
 
となり、
 要素1 が欲しい場合 引数に 「1」を指定する事で 『あいうえお』が返ります。
 要素2 が欲しい場合 引数に 「2」を指定する事で 『いうえ』が返ります。
 
F1 は、要素1番目を返す フィールド名 です。
 
クエリ デザインビュー ですと
 
フィールド に、
 F1 : getString([フィールド名],1)
とする事になります。

回答
投稿日時: 21/03/12 09:35:40
投稿者: Suzu

追記
 
今回の例では、分割したい要素数 は、3 でしたが、
実際には、レコードに拠っては 3以外の事もありえると考えました。
 
「3」の様に、固定の場合、
【A】あいうえお【B】いうえ【C】かきく → ・あいうえお・いうえ・かきく
の様に、返す関数にしてしまえば
 
 
クエリの演算フィールドのみで、InStr関数、Mid関数 で簡単に処理できます。
 
ですが、要素数が不定の場合、
クエリには予め、多めにフィールドを用意する事になります。
要素が無い演算フィールドの結果としてエラーが表示される事になりますので
エラー表示を防ぐ為には、InStr関数、Mid関数 の他に、条件分岐が必要になります。
この条件分岐をクエリの演算フィールドで行おうとすると、複雑になりがちです。
 
それを防ぐ為、VBA側で、要素数が無い場合には、空白文字列を返す様にしています。
 
 
【A】あいうえお【B】いうえ【C】かきく
  要素数が 3
に対し
 getString([フィールド名],4) AS F4 では、空白文字列を返すという事です。

投稿日時: 21/03/13 06:31:31
投稿者: あのこ

ご丁寧にありがとうございます!
ご教示いただいた方法で、思った結果を
返すことが出来ました。
なかなか奥深い凄い技、勉強になりました。
感謝いたしますらありがとうございました。