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

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

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

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

9回答

3334閲覧

【VBA】正規表現

joucomi

総合スコア30

VBA

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

1グッド

6クリップ

投稿2015/02/22 13:57

23歳OLです。

VBAと正規表現についての質問です。

▼やりたいこと

1 | 0 |1234567890 | 2014-2-22 22:22:22.06+09
という数列から
1234567890 という数字のみを抜き出したいです。
正確には2本目の|と3本目の|の間に入っている様々な数字です。
※桁数が固定されていません。

▼実際書いたコード

Sub Sample2()
Dim RE, strPattern As String, i As Long, msg As String, reMatch
Set RE = CreateObject("VBScript.RegExp")
strPattern = "☆この部分☆"
With RE
.Pattern = strPattern
.IgnoreCase = True
.Global = True
For i = 1 To 10
Set reMatch = .Execute(Cells(i, 1))
If reMatch.Count > 0 Then
msg = msg & reMatch(0).Value & vbCrLf
End If
Next i
End With
MsgBox msg
Set reMatch = Nothing
Set RE = Nothing
End Sub

☆この部分に☆に何を入れればよいでしょう?
ご指導よろしくおねがいします。

act823👍を押しています

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

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

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

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

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

guest

回答9

0

ベストアンサー

>「J列5行目から14行目の内容の"|"で区切った3つめを取り出して、それを各行のI列に入れる」ですか?

まさにこれです!言葉足らずですみません。。。

ということであれば、

lang

1Sub 三番目取り出し() 2Dim i As Integer, msg As String, x() As String 3Worksheets("sheet1").Activate 4For i = 5 To 14 5 x = Split(Cells(i, 10), "|") 6 If UBound(x) >= 2 Then 7 msg = Trim(x(2)) 8 Else 9 msg = "" 10 End If 11 Cells(i, 9) = msg 12Next i 13End Sub

投稿2015/02/24 06:16

otn

総合スコア84555

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

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

joucomi

2015/02/24 06:33

解決しました!皆様長い間ありがとうございました。 ベストアンサーをいただいた以外の方も、とても勉強になり、今後のプログラムの意欲がわきました。 どこか勉強会とか行ってみたいです♪
guest

0

これは、取り出したいのは「|」で区切られた三番目の項目だけでしょうか?

投稿2015/02/22 17:15

shinosan

総合スコア209

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

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

joucomi

2015/02/23 02:45

三番目だけです!この三番目には何が何ケタの整数が入るかわかりません。
guest

0

正規表現は

strPattern = "[0-9]+"

でよろしいかと。
「実際書いたコード」にある、

Set reMatch = .Execute(Cells(i, 1))

でreMatchにコレクション(配列のようなものと考えてよいです)でマッチした文字がすべて返されてきます。
ループで回して、reMatchに帰ってきた文字列をすべて連結すれば、数字のみをすべて抽出できます。
例えば、先頭のDimにjを追加しておいて、Forループのところを下記のようにしたらどうでしょう。

For i = 1 To 10 Set reMatch = .Execute(Cells(i, 1)) For j = 0 To reMatch.Count-1 msg = msg & reMatch(j).Value WScript.echo reMatch.Count Next j Next i

投稿2015/02/22 14:42

tohshima

総合スコア374

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

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

joucomi

2015/02/23 02:52

>strPattern = "[0-9]+" 一番前の整数だけ取り出すことができました。 ただ上記質問追記のせいなのでしょうか? 三番目の数字を取り出すことができません。 申し訳ないのですが、もう一度ご確認いただくことは可能でしょうか・・・。
tohshima

2015/02/23 13:37

すでにたくさんの回答が付いていますが、一応・・・ 3番目だけ取りたいのであれば、 reMatch(2).Value とすれば取り出せます。
guest

0

ようやくあなたのやりたいことが理解できと思います。
以下のコードをそのまま使ってみてください。

Sub Sample3()
Dim RE, strPattern As String, i As Long, msg As String, reMatch
Set RE = CreateObject("VBScript.RegExp")
strPattern = ".|.|(\d+) |.*"
With RE
.Pattern = strPattern
.IgnoreCase = True
.Global = True
For i = 1 To 10
Set reMatch = .Execute(Cells(i, 1))
If reMatch.Count > 0 Then
msg = msg & reMatch(0).submatches(0) & vbCrLf
End If
Next i
End With
MsgBox msg
Set reMatch = Nothing
Set RE = Nothing
End Sub

投稿2015/02/24 00:33

Guu

総合スコア142

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

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

joucomi

2015/02/24 05:33

ご返事ありがとうございます。 すみません!追記にも書いてある通り、メッセージボックスは使わないタイプを作りたいと思っています。。。 せっかく書いていただいたのに申し訳ありません。 何かの参考にいたします。
Guu

2015/02/24 05:59

ソースを見たのですが、たぶんイロイロ間違っていると思います。 完全な一般素人でしょうか? 素人でも構わないのですが、レベルが判らないとどこから伝えれば良いのか判りません。 なぜか判りませんが、4行目10列からデータを入れることになっているのでご自分でソースを書いたわけではないのなら間違わないようにしてください。 これはなるべく貴女のソースを生かしたものです。その後に多分間違っているであろう個所も直したものも入れておきます Sub 正規表現() Dim re, strPattern As String, i, c As Long, msg As String, reMatch Set re = CreateObject("VBScript.RegExp") Worksheets("sheet1").Activate strPattern = ".*\|.*\|(\d+) \|.*" With re .Pattern = strPattern .IgnoreCase = True .Global = True For i = 1 To 10 Set reMatch = .Execute(Cells(i + 4, 10)) If reMatch.Count > 0 Then msg = msg & reMatch(0).submatches(0) & vbCrLf End If Next i End With For c = 1 To 5 Cells(c + 4, 9) = msg Next c Set reMatch = Nothing Set re = Nothing End Sub Sub 正規表現2() Dim re, strPattern As String, i, c As Long, msg As String, reMatch Set re = CreateObject("VBScript.RegExp") Worksheets("sheet1").Activate strPattern = ".*\|.*\|(\d+) \|.*" With re .Pattern = strPattern .IgnoreCase = True .Global = True For i = 1 To 10 Set reMatch = .Execute(Cells(i + 4, 10)) If reMatch.Count > 0 Then Cells(i + 4, 9) = reMatch(0).submatches(0) & vbCrLf End If Next i End With Set reMatch = Nothing Set re = Nothing End Sub
guest

0

Okwaveに回答したものの焼き直しですが、

lang

1Sub 三番目取り出し() 2Dim i As Long, c As Long, msg As String, x() As String 3Worksheets("sheet1").Activate 4For i = 1 To 10 5 x = Split(Cells(i + 4, 10), "|") 6 If UBound(x) >= 2 Then 7 msg = msg & Trim(x(2)) & vbCrLf 8 End If 9Next i 10 11For c = 1 To 5 12 Cells(c + 4, 9) = msg 13Next c 14End Sub

他の回答のコメントで「無効なインデックス」となるのは、対象セルの中に|の個数が足りないところがあるんでしょう。上記では、それをUBound(x)で判断してます。

投稿2015/02/23 11:53

otn

総合スコア84555

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

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

joucomi

2015/02/23 12:46

ありがとうございます!確認してみます(^^)/
joucomi

2015/02/24 05:35

試してみました。 しかしながら置き換えた結果がすべて同じセルに入ってしまいます。 セルを分割して 1234567890       1 | 0 |1234567890 | 2014-2-22 22:22:22.06+09 というような形にしたいです。
otn

2015/02/24 05:52

質問追記のプログラムをSplitを使って書き直しただけなのですが。 追記のプログラムは、「J列5行目から14行目の内容の"|"で区切った3つめを取り出して、それらを全部改行で繋げ、繋げた結果を、I列5行目から9行目に入れる」ですが、 実はしたいことはそれでないということですか? やりたいことをうまく書けないなら、日本語で書いても良いかと思います。 >1234567890       1 | 0 |1234567890 | 2014-2-22 22:22:22.06+09 「J列5行目から14行目の内容の"|"で区切った3つめを取り出して、それを各行のI列に入れる」ですか?
joucomi

2015/02/24 05:54

>「J列5行目から14行目の内容の"|"で区切った3つめを取り出して、それを各行のI列に入れる」ですか? まさにこれです!言葉足らずですみません。。。
guest

0

正規表現で処理をすることが重要なのであればスルーしていただくとして
この処理の場合 msg = Split(対象文字列, "|")(2) のほうが手っ取り早くないですか?

投稿2015/02/23 06:13

yunn

総合スコア144

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

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

joucomi

2015/02/23 06:28

VBA内の処理として 対象文字列にはどうやって入れるのでしょうか? セルのナンバー たとえばmsg = Split(cells(1.1), "|")(2) のような形にするのでしょうか?
yunn

2015/02/23 06:33

そうです。追記のコードでいえば Cells(i + 4, 10) ですね。
joucomi

2015/02/23 06:42

Sub 正規表現() Dim re, strPattern As String, i, c As Long, msg As String, reMatch Set re = CreateObject("VBScript.RegExp") Worksheets("sheet1").Activate With re .Pattern = strPattern .IgnoreCase = True .Global = True For i = 1 To 10 Set reMatch = .Execute(Cells(i + 4, 10)) If reMatch.Count > 0 Then msg = Split(Cells(i + 4, 10), "|")(2) ’☆ End If Next i End With For c = 1 To 5 Cells(c + 4, 9) = msg Next c Set reMatch = Nothing Set re = Nothing End Sub これで書いてみたのですが動かないです・・・・。 インデックスの有効な値がないそうで☆のところに黄色いラインが入ります
yunn

2015/02/23 06:57

ごめんなさい、正規表現使わない方法なので Sub 正規表現() Worksheets("sheet1").Activate For i = 1 To 10 msg = Split(Cells(i + 4, 10), "|")(2) Next i For c = 1 To 5 Cells(c + 4, 9) = msg Next c End Sub こうかな? …検索は10件で出力は5件でいいんですかね…?
joucomi

2015/02/23 07:32

Sub 正規表現() Dim msg As String Dim i As Long Dim c As Long Worksheets("部分RESULT").Activate For i = 1 To 5 msg = Split(Cells(i + 4, 10), "|")(2) ’ここに無効なインデックスと表示されます。 Next i For c = 1 To 5 Cells(c + 4, 9) = msg Next c End Sub こうやって書いてみましたー。 検索5件で 出力5件です。
joucomi

2015/02/23 07:33

やっぱり動きませんねーどうしてでしょうか。
yunn

2015/02/23 07:47

うーん(^_^;) 無効なインデックスってことは多分 "|" で Split が出来てないんですね。 Sub test() MsgBox Split(" 1 | 0 |1234567890 | 2014-2-22 22:22:22.06+09", "|")(2) End Sub これで、正しく "1234567890" がMsgBoxで表示されるかどうか見てみて これも動かない、となると…バージョンとか環境とかが(私のPCとは)異なる、ということで、出来ないやり方なのかも知れません。 正規表現のほうで正解に近付いていたなら、そちらのほうがいいかもです。
joucomi

2015/02/23 11:37

Sub test() MsgBox Split(" 1 | 0 |1234567890 | 2014-2-22 22:22:22.06+09", "|")(2) End Sub これは表示できました!
joucomi

2015/02/23 11:47

今試してみたところ 1  1 |   0 |12345678 | 2014-2-22 22:22:22.06+09  1  1 |   0 |1234567890 | 2014-2-22 22:22:22.06+09  1  1 |   0 |1234567890 | 2014-2-22 22:22:22.06+09  1  1 |   0 |123 | 2014-2-22 22:22:22.06+09  1  1 |   0 |1 | 2014-2-22 22:22:22.06+09  このような形でスプリットしました! ※最初の1がなぜか抽出された結果です。。。 どうしてこうなってしまうんだろう。。。
guest

0

「strPattern = "^\d*$"」または「strPattern = "^\d+$"」で、
MsgBoxに「1」「0」「1234567890」が表示されます。
「1」しか表示されない場合は、行と列が逆になってます。
1桁を省くなら(2桁以上)、
「strPattern = "^\d.\d*$"」で、MsgBoxに「1234567890」が表示されます。

投稿2015/02/23 05:51

act823

総合スコア266

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

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

0

strPattern = " .|.|\d+ |.* "
これで良いと思います
目的の数列を抜き出したいのなら、" .|.|(\d+) |.* "とカッコで括って、submatchを見れば良いと思います。

投稿2015/02/23 01:16

Guu

総合スコア142

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

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

Guu

2015/02/23 02:25

最後の列をタイムスタンプと仮定すれば以下のようにして精度を上げることができます。 ".*\|.*\|(\d+) \| \d{4}\-\d{1,2}\-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}.\d\d+\d\d" 固定条件を出来るだけ絞ればマッチ精度はあがります
joucomi

2015/02/23 02:47

ご返事ありがとうございます。 上記いただいたコードが使えませんでした。。。。
Guu

2015/02/23 03:00

?? 以下で確認できましたよ 疑わしきは、ダブルコーテーションは、正規表現ではなく、文字列の区切りとして入れてあります。 なので以下のように書きます。 あとは文字列の始まりのスペースがあいまいなので必要無ければ削ってください。 strPattern = ".*\|.*\|\d+ \|.*" 又は strPattern = ".*\|.*\|(\d+) \| \d{4}\-\d{1,2}\-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}.\d\d+\d\d"
joucomi

2015/02/24 05:52

Sub 正規表現() Dim re, strPattern As String, i, c As Long, msg As String, reMatch Set re = CreateObject("VBScript.RegExp") Worksheets("sheet1").Activate strPattern = ".*\|.*\|(\d+) \| \d{4}\-\d{1,2}\-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}.\d\d+\d\d""" With re .Pattern = strPattern .IgnoreCase = True .Global = True For i = 1 To 10 Set reMatch = .Execute(Cells(i + 4, 10)) If reMatch.Count > 0 Then msg = msg & reMatch(0).Value & vbCrLf End If Next i End With For c = 1 To 5 Cells(c + 4, 9) = msg Next c Set reMatch = Nothing Set re = Nothing End Sub こうやって見ましたが、 反応しませんねー。 cells(10,5)に入っているものをcells(10,4)に移しながら下降していくのができません。
Guu

2015/02/24 06:05

それは正規表現文字列の最後がダブコーテーション(”)だらけだからです
guest

0

以下のパターンを投げ込めば、
\s*([0-9]*)\|\s*([0-9]*)\|\s*([0-9]*)\|(.*)
reMatch(3).Valueで拾えそうですね。

ただ、VBAの正規表現には詳しくないので間違えているかもしれません。

投稿2015/02/22 14:32

satanabe1

総合スコア113

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問