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

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

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

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

4回答

2302閲覧

Excelマクロでテキストファイルから特定文字列を含む1レコードを取得する方法

dai3922

総合スコア34

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2017/11/30 08:12

編集2017/12/26 06:59

Excelマクロで下記のようなテキストファイルから、
「Release」から始まるレコードを取得する方法を教えて頂けますでしょうか?

テキストファイルの仕様として、
1.テキストファイルによって「Version」を含むレコードが増減します。
2.「Release」で始まるレコードは必ず1レコードのみです。
3.「Release」レコードが何行目に位置するかは変わります。
4.「Release」レコードの文字列長は可変です。(「4.7.1 Windows hogehoge edition」などと記載される場合もあります。)

以上です。
instr関数とMid関数を使用していましたが、
「4.7」は取得できるものの、上記カッコ内の様にその後に文字列が続く場合があり、
理想としては「Release」で示されるValue値を改行コード手前まで取得したいと考えております。

恐れ入りますが、宜しくお願い致します。

=テキストファイルの内容=
Type Value


Version 2.0.50727.5420
Version 3.0.30729.5420
Version 3.0.4506.5420
Version 3.0.6920.5011
Version 3.5.30729.5420
Version 4.0.0.0
Release 4.7
Version 4.7.02053

VBA

1'2017/12/22追記 2'Alllog4は本テキストファイルの全文を格納しています。 3 With fso.OpenTextFile(logPath & buf4, 1) ' 4 Alllog4 = .ReadAll 5 .Close 6 End With 7'現状使用しているinstr関数とMid関数のコードです 8 Net_ver = Mid(Alllog4, InStr(1, Alllog4, "Release") + 8, 7) '「Release」表記のあとのバージョンを求める。

※皆様どうもありがとうございました。
皆様のご指摘どおり、「vbCrLf」の指定で行を区切ることで実現することが出来ました。
ベストアンサーは非常に迷いましたが、現コードの一文をそのまま修正して実現することが出来ましたので
h.horikoshi様とさせて頂きました。
他の回答者の皆様には申し訳ございませんが、一つ一つのご回答がとても参考になりました。
本来、お礼をこちらに記載することは不適切かもしれませんが
記載する場所が分かりませんでしたのでこちらで述べさせて頂きます。
貴重なお時間を割いて頂き、ありがとうございました。

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

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

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

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

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

ExcelVBAer

2017/12/01 00:18

Instr Mid で処理している部分のコードをご提示ください
dai3922

2017/12/22 02:43

ご連絡が遅くなりすみません。追記致しました。
guest

回答4

0

Split を使用して、改行コードで分割し、該当行を探す方法が一般的かと。

VBA

1Dim SplitAry() As String 2SplitAry = Split(Alllog4,vbCrLf) ’改行コードによって調整 3 4Dim i As long 5for i = Lbound( SplitAry ,1) to Ubound( SplitAry ,1) 6 If Instr(1,SplitAry(i),"Release") <> 0 Then 7 Net_ver = SplitAry(i) 8     Exit For 9 End if 10Next

投稿2017/12/22 04:09

ExcelVBAer

総合スコア1175

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

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

dai3922

2017/12/26 06:50

ご回答頂き、ありがとうございます。 「vbCrLf」の部分を考慮できていなかったことが原因でした。 シンプルでわかりやすいコーディングを教えて頂きありがとうございました。 参考にさせて頂きます。
guest

0

instr関数とMid関数を使用していましたが、

とあるので、一連の処理はできているものと判断します。
であれば、単に行データからどう抜き出すかの回答でよいですよね。
Line変数に行データがあると仮定して、次のようにすればRelease以降の文字列が取得できます。

VBA

1Mid(Line, Len("Release ") + 1)

更新された質問の回答です。
ReadAllでまとめて変数に保持しているのであれば、改行コード単位で分割してから処理するのが良いと思います。

VBA

1 Const WORD = "Release" ' 検索対象の文字列 2 Dim wordlen As Integer ' 検索対象の文字列の長さ 3 Dim lines As Variant ' 分割した行を格納する変数 4 Dim line As String ' 1行分 5 6 ' 改行コードで分割 7 lines = Split(Alllog4, vbCrLf) 8 9 ' 検索対象の文字列の長さを取得 10 strlen = Len(WORD) 11 12 ' 行ごとにループ 13 For Each line In lines 14 ' 行の先頭に検索対象文字列があるか 15 If Left(line, wordlen) = WORD Then 16 ' 検索対象文字列以降を抽出 17 Debug.Print Mid(line, wordlen + 2) 18 End If 19 Next

投稿2017/11/30 08:32

編集2017/12/22 07:29
ttyp03

総合スコア16996

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

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

dai3922

2017/12/22 02:56

ご連絡が遅くなりすみません。 ご回答ありがとうございます。 上記で追記しました「Alllog4」という変数には本テキストファイルのデータ全行が格納されている状態です。 そのためか、Mid関数でうまく取得できていないのが現状です。 情報が足らず申し訳ありませんでした。
ttyp03

2017/12/22 04:24

追記しましたのでご確認ください。
dai3922

2017/12/26 06:53

当初よりご親切に再度ご回答頂き、ありがとうございます。 「vbCrLf」の部分、ご指摘の通りここの単位で区切ることが出来ていなかったことが原因でした。 コード内のコメントも非常に分かりやすくご記載頂き、感謝しております。 今後の学習で参考にさせて頂きます。 どうもありがとうございました。
guest

0

ベストアンサー

質問者さんの考え方でいいと思いますけど…

Net_ver = Split(Mid$(vbLf & Alllog4, InStr(Alllog4, vbLf & "Release") + 2), vbLf)(0)

テキスト中にReleaeが1つしかないならInstrで十分。
Releaeの前に改行つけるのは行頭検出。
Alllog4の前に改行つけるのはReleaseがテキストの先頭にあるときの対策。
Relase以降を改行でsplitしてその最初の要素をとればよい。

※vbLfはテキストの改行コードにあわせてください。
※上記の他、正規表現を使うともっと簡単です。

投稿2017/12/25 00:47

h.horikoshi

総合スコア505

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

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

dai3922

2017/12/26 06:32

ありがとうございます、まさに実現したいことが出来ました!
guest

0

テキストファイルを取得する際に行単位で読むようにすれば話は早いです。

Const CS_SEARCH As String = "Release" Dim sLine As String Dim f Set f = fso.OpenTextFile(logPath & buf4, 1) 'ファイルの終わりまでループ処理 Do Until f.AtEndOfLine '1行ずつ読み込む sLine = f.ReadLine If InStr(sLine, CS_SEARCH) > 0 Then Net_ver = Mid(sLine, InStr(1, sLine, CS_SEARCH) + Len(CS_SEARCH)) '「Release」表記のあとのバージョンを求める。 Exit Do End If Loop

もし後続処理との兼ね合いなどでどうしても全文で取得しておく必要があるのであれば、Split関数を使い改行で区切るという方法もあります。

'Alllog4は本テキストファイルの全文を格納しています。 With fso.OpenTextFile(logPath & buf4, 1) ' Alllog4 = .ReadAll .Close End With Const CS_SEARCH As String = "Release" Dim sLine As String Dim ary, i '改行で分割した文字列配列を作成 ary = Split(Alllog4, vbCrLf) '文字列配列の数だけループ(行ループ) For i = 0 To UBound(ary) - 1 '配列から1行分取り出す sLine = ary(i) '"Releace"の文字列が見つかれば If InStr(sLine, CS_SEARCH) > 0 Then Net_ver = Mid(sLine, InStr(1, sLine, CS_SEARCH) + Len(CS_SEARCH)) '「Release」表記のあとのバージョンを求める。 Exit For End If Next

投稿2017/12/22 04:58

編集2017/12/22 05:01
jawa

総合スコア3013

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

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

dai3922

2017/12/26 06:53

ご親切にご回答頂きありがとうございました。 ご指摘の通り、全文取得する必要はそもそもありませんでした。 (別の箇所の別の処理にはなりますが全文取得で成功していたため、効率を捨てて安全に走ってしまいました。) お教え下さった「vbCrLf」の指定で実現することが分かりました。 どうもありがとうございました。 助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問