質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

1536閲覧

【VBA】マッチしない想定の正規表現にマッチしてしまう

Chandler_Bing

総合スコア673

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/11/11 01:34

表題の通りですが、VBAの正規表現が上手く機能しません。

マッチさせたい文字列①
「OK改行yyyy/mm/dd」か「NG改行yyyy/mm/dd」
例)
OK
2020/11/11

例)
NG
2020/11/11

マッチさせたい文字列②
「NG改行yyyy/mm/dd改行OK改行yyyy/mm/dd」
例)
NG
2020/11/11
OK
2020/11/12

★プログラムの概要★
入力されたセル値に対して①に合致するか判定し、合致しない場合は、②に合致するか判定する。
どちらにも合致しない場合は、ダイアログボックスに、どのセルへの入力値がマッチしていないか表示する。

★事象の詳細★
以下のセル値を入力しています。

OK
2020/11/11
OK
2020/11/11

vba

1Sub checkValue() 2 3 Dim date_pattern As String '// 日付の正規表現パターン 4 Dim is_correct As Boolean '// テスト結果入力値の判定フラグ 5 Dim msg As String '// ダイアログボックスに表示するメッセージ 6 7 '// デフォルト値を設定 8 is_correct = True 9 date_pattern = "[0-9]{4}/(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])" '// yyyy/mm/dd 10 11 '// 正規表現オブジェクトを生成 12 Set re = New RegExp 13 re.Pattern = "^(T|NT)|(OK|NG)\n" & date_pattern & "$" '// 「T」か「NT」か「OK\nyyyy/mm/dd」か「NG\nyyyy/mm/dd」 14 15 16 For i = 1 To 5 17 For j = 1 To 7 18 ' // 正規表現にマッチしない場合 19 If re.Test(Worksheets(2).Cells(i, j)) = False Then '// ①の条件判定 20 Debug.Print "1 if" 21 '// 「T」か「NT」か「NG\nyyyy/mm/dd\nOK\nyyyy/mm/dd」か 22 re.Pattern = "^NG\n" & date_pattern & "\nOK\n" & date_pattern & "$" 23 ' // 正規表現にマッチしない場合 24 If re.Test(Worksheets(2).Cells(i, j)) = False Then '// ②の条件判定 25 '// フラグを偽にする 26 is_correct = False 27 End If 28 Else 29 Debug.Print "1 else" 30 End If 31 32 '// テスト結果入力値が不正であれば終了 33 If is_correct = False Then 34 msg = Worksheets(2).Cells(i, j).Address(RowAbsolute:=False, ColumnAbsolute:=False) & "の値が不正です。(" & Worksheets(2).Cells(i, j) & ")" 35 MsgBox msg 36 Exit Sub 37 End If 38 Next j 39 Next i 40 msg = "問題ありません。" 41 MsgBox msg 42End Sub

この場合、①と②のどちらにも、マッチしないはずですが、イミディエイトウィンドウに「"1 else"」と表示されるので、①の判定部分でマッチしています。なぜでしょうか。ソースコードでおかしな部分がありますでしょうか。

※補足
・(T|NT)の部分は気にしないでください。上手く動作しています。
・ループ変数の「i」「j」はセルの位置を指します。

以上です。
よろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

全体のパターンが^(T|NT)|(OK|NG)\n(日付パターン略)$となりますが、これでは「TまたはNTで始まるもの」と「(OKまたはNG)(改行)日付で終わるもの」という選択となっています。

投稿2020/11/11 01:41

maisumakun

総合スコア145208

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chandler_Bing

2020/11/11 01:54

ありがとうございます。 ではどのように記述すれば、 「OK」か「NG」で始まり、改行、日付で終わるパターン か 「T」か「NT」 を判定できますでしょうか。 ^(OK|NG)\n(日付パターン略)$ のみを記述し、TとNTは、また別の条件分岐で聞いた方がよいのでしょうか。
maisumakun

2020/11/11 01:56 編集

^と$の間を1つの丸括弧に入れてください。 ^(T|NT|(OK|NG)\n(日付パターン略))$
maisumakun

2020/11/11 01:57

> (T|NT)の部分は気にしないでください それがあるがゆえの問題だったのですが…
Chandler_Bing

2020/11/11 02:03

なるほど、、、お騒がせしました。 ありがとうございました。
Chandler_Bing

2020/11/11 02:17

申し訳ありません。 もう一点、追加で質問させて下さい。 ^(T|NT)|(OK|NG)\n(日付パターン略)$ 上記の正規表現の場合は「「TまたはNTで始まるもの」と「(OKまたはNG)(改行)日付で終わるもの」」になると回答を頂きました。 始まり(^)が(T|NT)の部分だけに影響し、終わり($)が(OK|NG)\n(日付パターン略)の部分だけに影響する理由は 「^(T|NT) OR (OK|NG)\n(日付パターン略)$」という判断になっており「^」と「$」が、 (T|NT)と(OK|NG)\n(日付パターン略)の両方それぞれに掛かっていないから、という認識であっていますでしょうか。
maisumakun

2020/11/11 02:19

そのとおりです。 なお、|で選択される両側に^と$を入れて、「^(T|NT)$|^(OK|NG)\n(日付パターン略)$」のような形で対応することもできます。
Chandler_Bing

2020/11/11 02:26

ありがとうございました。 正規表現への理解が、また深まりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問