人に聞けない痔の悩み、これでスッキリ >>

vbaで複数行のデータの一部を抜き出そうと思っています。
下記のようにすると、抜き出したデータの先頭に改行がついてしまいます。
何かいい方法はないでしょうか。


data = "start" & vbCrLf  & "ABC" & vbCrLf & "DEF" & vbCrLf & "GHI" & vbCrLf & "end"

Set re = New RegExp

re.Pattern = "start((.|\n)*?)end"

re.MultiLine = True

Set mc = re.Execute(data)

For i = 0 To mc.Count - 1

MsgBox m.SubMatches(0)

Next i


上記を実行すると

vbCrLf  & "ABC" & vbCrLf & "DEF" & vbCrLf & "GHI" & vbCrLf

となってしまいます。

”ABC”から抜き出す場合、正規表現をどう書けばいいのでしょうか。
よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

こんにちは。



vbCrLfを表すパターンは、
 \r\n
です。

Sub Re8780307()
Dim re As VBScript_RegExp_55.RegExp
Dim mc As VBScript_RegExp_55.MatchCollection
Dim m As VBScript_RegExp_55.Match
Dim Data
  Data = "start" & vbCrLf & "ABC" & vbCrLf & "DEF" & vbCrLf & "GHI" & vbCrLf & "end" & vbCrLf & _
    "start" & vbCrLf & "JKL" & vbCrLf & "MNO" & vbCrLf & "PQR" & vbCrLf & "end"
  
  Set re = New RegExp
  re.Global = True
  re.MultiLine = True
  re.Pattern = "start(\r\n((.|\r\n)*?)\r\n)end"
  
  Set mc = re.Execute(Data)
  For Each m In mc
    Debug.Print "■"; m.SubMatches(1); "■"
  Next
End Sub

みたいなことをなさりたいのでは?
    • good
    • 1
この回答へのお礼

ありがとうございます。

すっかり、「¥r」の存在を忘れていました。
たぶん、これでスッキリ解決だと思います。
今からテストしてみます。

お礼日時:2014/10/06 20:23

> re.Pattern = "start((.|\n)*?)end"


ここでstartの後の改行をかっこの外に出しておくべきなのでは?
re.Pattern = "start\n((.|\n)*?)end"
    • good
    • 0
この回答へのお礼

ありがとうございます。

今回、質問に書いたプログラムと、実際のプログラムは少し違います。
プログラムの一部を、簡略化しています。

実際は、正規表現でマッチしたのを、分割してコレクションに入れています。
その分割したデータを、再分割するところのプログラムが、今回質問したところです。

そこでは、なぜか正規表現がうまくマッチしません。

>re.Pattern = "start\n((.|\n)*?)end"

これも試してみましたが、startの文字を入れるとマッチしなくなります。
どうも、コレクションの挙動がおかしいので、その辺から見直してみます。
ありがとうございました。

お礼日時:2014/10/06 07:50

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qvbaの正規表現で、マッチした一部分を抽出したい

accessの正規表現で、マッチした部分の一部を取り出したいと思っています。

秀丸で言えば、
------------------------

文字列 あいうえお
↓↓↓
正規表現 あ(.*)お
置き換え文字 \1
↓↓↓
抽出 いうえ

------------------------
って感じの「¥1」みたいなのがほしいと考えています。

現在、下記のような感じで、対象文字を抽出しています。
ここから、また正規表現でほしい部分を抽出しなければいけないのでしょうか?



【上の例で言えば、「あいうえお」を抽出する関数】

------------------------
Function 抜き出し(ByVal 指定文字列 As String) As String

Dim 正規表現, 一致集団, 一致要素

Set 正規表現 = CreateObject("VBScript.RegExp")

正規表現.Pattern = "購入日時[0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日 [0-9]{1,2}時[0-9]{1,2}分"
正規表現.MultiLine = True

Set 一致集団 = 正規表現.Execute(指定文字列)

For Each 一致要素 In 一致集団

抜き出し = 一致要素.Value
Exit For
Next
End Function
------------------------

これだと、

購入日時2012年1月25日 17時53分

がマッチします。
でもほしいのは、

2012年1月25日 17時53分

の部分だけ。

何かいい方法は無いでしょうか?
よろしくお願いします。

accessの正規表現で、マッチした部分の一部を取り出したいと思っています。

秀丸で言えば、
------------------------

文字列 あいうえお
↓↓↓
正規表現 あ(.*)お
置き換え文字 \1
↓↓↓
抽出 いうえ

------------------------
って感じの「¥1」みたいなのがほしいと考えています。

現在、下記のような感じで、対象文字を抽出しています。
ここから、また正規表現でほしい部分を抽出しなければいけないのでしょうか?



【上の例で言えば、「あいうえお」を抽出する関数】

------------------------
Func...続きを読む

Aベストアンサー

今日を。

正規表現で解決するとすれば次のようになります。

Sub test()
Dim sss As String
sss = "aaaa購入日時2012年1月25日 17時53分bbbbcccc購入日時2012年1月25日 17時53分dddd"
' sss = "aaa"
sss = 抜き出し(sss)
Debug.Print sss
End Sub

Function 抜き出し(ByVal 指定文字列 As String) As String
Dim 正規表現, 一致集団, 一致要素
Set 正規表現 = CreateObject("VBScript.RegExp")
正規表現.Pattern = "購入日時([0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日 [0-9]{1,2}時[0-9]{1,2}分)"
'パターンを括弧で囲む
正規表現.MultiLine = True
Set 一致集団 = 正規表現.Execute(指定文字列)
'正規表現.Global = True を指定していないので、一件だけ抽出する。
Debug.Print 一致集団.Count

If 一致集団.Count > 0 Then
抜き出し = 一致集団(0).SubMatches(0)
'.SubMatches(0) 'Patternを()でククッタ箇所取り出し
End If
End Function


それ以外に、置き換えで、"購入日時"を空白にするとか
Right関数で、4文字を取り除くとか

今日を。

正規表現で解決するとすれば次のようになります。

Sub test()
Dim sss As String
sss = "aaaa購入日時2012年1月25日 17時53分bbbbcccc購入日時2012年1月25日 17時53分dddd"
' sss = "aaa"
sss = 抜き出し(sss)
Debug.Print sss
End Sub

Function 抜き出し(ByVal 指定文字列 As String) As String
Dim 正規表現, 一致集団, 一致要素
Set 正規表現 = CreateObject("VBScript.RegExp")
正規表現.Pattern = "購入日時([0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日 [0-9]{1,2}時[0-9]{1,2}分)"
'パターン...続きを読む

QVBAでfor文の中で、continueしたい

お世話になります。
VBAのfor文の中で、ある条件に合致したら、for の先頭に戻りたいのですが、
方法が分かりません。

VB.net 等の「 Continue For」に当たるものは、VBAに
ないのでしょうか?

何卒宜しくお願いします。

Aベストアンサー

Continue For は昔の VB6 までに物には実装されていませんね VB6 使いの私は知らなかった

for の先頭に戻りたいのではなく、 Next の直前に飛びたいのですよね?
幸いにも VBA には Goto ステートメントがありますので

Sub Sample1()
For i = 1 To 10
If 意除外条件 Then GoTo Next_no_mae

通常の総理

Next_no_mae:

Next i

End Sub

じゃダメですか?
これなら For の直後に飛ぶ事も可能ですが

もしくはこれぐらいしか対処方法はないのでは?
Sub Sample2()

For i = 1 To 10
If 除外条件 Then
Else
通常の総理
End If
Next i

End Sub

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QEXCEL(VBA) 末尾の改行のみ削除したい

[ALT]-[ENTER]を使い、セル内を改行した文章があります。
その文章の末尾にある改行のみ削除したいのですが
ReplaceやRtrimを使うと、末尾以外の改行も削除されたりして、
思うような結果が得られません。

イメージとしては以下のようにしたいと思っております。

↓このように表示されているものを
-----------------------
本日は晴天なり。

1.AAAAA
2.BBBBB

-----------------------

↓このようにしたい
(2.BBBBB 以降にある改行のみ削除したいです。)
-----------------------
本日は晴天なり。

1.AAAAA
2.BBBBB
-----------------------

判りづらい説明で申し訳ありません。
何か良い方法はないでしょうか?

Aベストアンサー

正規表現で置換すればできると思います。
A1の文字列の末尾にある改行を削除してA2に表示します。

参照設定でVBScript Regular Expressions ?.?にチェックを入れる
Sub test()
Dim re As New RegExp
re.Pattern = "\n+$"'末尾の1個以上の改行
Range("A2") = re.Replace(Range("A1"), "")
Set re = Nothing
End Sub

または、
Sub test()
Dim re As Object
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\n+$"'末尾の1個以上の改行
Range("A2") = re.Replace(Range("A1"), "")
Set re = Nothing
End Sub

QVBA オブジェクトが空かどうか判定する

皆様のお知恵を拝借させてください。

エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト
が入っているかどうか検査したいのですがどうしたらいいでしょうか。

例えば---
Dim a As Workbook
If a <> nothing then ←この部分が分からない。このままだとエラー。
処理
End if
---------
環境
エクセル2003
WinXPsp1

Aベストアンサー

もし、aが空だったら
If a Is Nothing Then 

もし、aが空じゃなかったら
If Not a Is Nothing Then

QEXCEL VBAで計算値を四捨五入、切り上げ、切捨てする方法

ネットで探してみたのですが、計算結果を四捨五入して特定のセルを
返すにはどうしたらいいのでしょうか?

Sub hokangosa()

Dim ZPS As Double
Dim ZPOS As Double
Dim DMN As Double
MsgBox (" >>> 補間誤差自動計算 <<< ")
MsgBox (" >>> 初期値入力します <<< ")
ZPS = InputBox(">>> ステップを入力してください<<<")
ZPOS = Sheet1.Cells(22, 4).Value
DMN = ZPOS / ZPS
Sheet1.Cells(23, 6).Value = DMN
End Sub

ここでDMNの値を四捨五入したいです。

またこれとは別に切上げ、切捨ても教えていただけるとありがたいです。

Aベストアンサー

DMN = Application.WorksheetFunction.Round(ZPOS / ZPS, 0)
で、四捨五入
DMN = Application.RoundDown(ZPOS / ZPS, 0)
で切り捨て
DMN = Application.RoundUp(ZPOS / ZPS, 0)
で切り上げです。

引数で、対象桁を変更できます。

Q別のシートから値を取得するとき

Worksheets("シート名").Activate
上記のを行ってから別シートの値を取得するのですが、
この処理を行うと指定したシートへ強制的にとんでしまいます。。。

※イメージ
For ~ To ~
  Worksheets("シートA").Activate
  シートAの値取得
       :
  Worksheets("シートB").Activate
  シートBの値取得
Next

このイメージ処理を行うとものすごい勢いで画面がチカチカします。。。
シートを変えずに他のシートから値を取得する方法はないのでしょうか。
教えてください!

Aベストアンサー

Worksheets("シートA").Range("A1")

みたいな感じでできませんか?

QFunctionの戻り値を配列にしたいのですが

vbを始めたばかりですがよろしくお願いします。

Functionの戻り値を配列にしたいのですが

Function fnc(ByVal a As Byte, ByVal b As Byte) As Integer()
fnc(0) = a + b
fnc(1) = a - b
End Function
というような使い方はできないのでしょうか?
一つのFunctionで二つの計算結果をかえすには
どうしたらよいのでしょうか?
お願いします。

Aベストアンサー

ローカル変数を使えば可能だと思いますよ

VB6.0の場合
Function fnc( byVal a as Byte, Byval b as Byte) as Integer
  dim ar(1) as Integer
  ar(0) = a + b
  ar(1) = a - b
  fnc = ar
End Function

VB.NETなら
Function fnc( byVal a as Byte, Byval b as Byte) as Integer
  dim ar(1) as Integer
  ar(0) = a + b
  ar(1) = a - b
  return ar
End Function

VB.NETでも fnc = ar と言った記述も出来ます

呼び出し側では 動的配列として返り値を受けます
dim results() as Integer
results = fnc( 5, 3 )
と言った具合です

QVBScript.RegExp正規表現での後方参照

VBScript.RegExpを使うと、VBA でも正規表現が使えることを最近知りました。
置換は Replaceメソッドでできるようですが、例えば Perlでの
s/(.)(.)/\2\1/;
のような置換(後方参照?前方参照?)はどうしたらできるでしょうか?

Aベストアンサー

$2$1の様に置換する文字列(の中でマッチしたもの)を指定することができます。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング