
文字列の入っている変数内で特定の文字列(今回はvbCrLf)が何個発生しているかを、高速に調べたいのですが、どのような方法があるでしょうか?
現在以下のことをやっています。
数千件のテキストファイルから特定文字列を検索しています。
検索を高速化するために、テキストファイルをバイナリーモードで1つの変数に読み込み、instr関数で検索しています。
見つかった場合、その位置から前にあるvbCrLfをInStrRev関数で、後ろにあるvbCrLfをinstr関数で位置を調べ、元の変数からmid関数で該当ラインを取り出しています。
検索はこれで可能ですが、特定文字列を調べたinstr関数の戻り値がテキストファイルの先頭からの位置(何桁目)なので、検索した文字列が何行目にあるか分かりません。
変数の検索文字が見つかった位置までの部分でvbCrLfが何個発生しているかが分かれば行数が判定できます。
vbCrLfを調べるinstr関数を何回も繰り返せば行数の判定は可能ですが、もっと高速に(一つの関数・命令で)調べることはできないでしょうか?
また他に行数を特定する良い方法があったら教えてください。
よろしくお願い申し上げます。
No.1ベストアンサー
- 回答日時:
行数をカウントするだけなら、FileSystemObjectのTextStreamを使用するのが最速だと思います。
改行コード以外の文字をカウントする場合は、RegExpクラスのmatchオブジェクトを使うのがよいと思います。
だいぶ以前に検証↓したことがありますので、ご参考まで。
http://fukkey.dyndns.org/pins/vb/021115/45028.html
参考URL:http://fukkey.dyndns.org/pins/vb/021115/45028.html
回答ありがとうございました。
RegExp、ヒントになりました。
> 改行コード以外の文字をカウントする場合は、
> RegExpクラスのmatchオブジェクトを使うのが
> よいと思います。
とのことですが、改行コードをカウントできました。
RegExpオブジェクトのPatternプロパティにvbCrLfを指定し
Executeメソッドを実行し、MatchesコレクションのCount
プロパティでvbCrLfの個数が分かりました。
FileSystemObjectのTextStreamはテキストファイルの全行数を調べる
ように思えますが、いかがでしょうか。
知りたいのは全行数ではなく、該当文字列のあった行です。
いずれにしても、先のMatchesコレクションで分かったvbCrLfの個数で
ラインが割り出せますので問題ありません。
No.7
- 回答日時:
こんにちは。
Wendy02です。>数千本のプログラムソースコード(即ちテキストファイル)があります。(既に存在しています)
私には、believe_meさんが、どういうご事情があるのか分かりませんが、失礼ですが、プロの方ではありませんか?私などアマチュアがあれこれ言える立場ではないかもしれませんが、わざわざ、アマチュアの使うOffice VBAなどは必要ないような気がします。
>全ソースコードを調べ、その項目名が使われるプログラム名(即ちファイル名)とその個所(何ライン目)の一覧表を作成する必要があります。
それは、Win では、Grep(GNUで、オープンソース付き)が一番なのです。しかし、それがダメなら、Grepの代わりに、擬似Grepの FindStr を使えばよいと思います。お仕事の立場上、手取り足取りのコードを書く必要はないと思いますから、すべてを書きませんが、以下のようなコードで取れます。後は、ファイル名:行数:内容 で、区切り文字が「:」ですから、それを、Split で区切れば、Excelのセルに取り出せます。
以前、私が作った検索プログラムを応用すれば、以下のようなコードになります。これは、テキスト出力までです。
ただし、以下は、Win2x系のみです。
Const QT As String = """"
Const OUTFNAME As String = "$SearchList.txt"
Const SEARCHWD As String = "RegExp" 'RegExpを探す
Cmd = "FindStr /rni " 'r =正規表現,n=行番号表示,i=大文字小文字無視
OutDir = ThisWorkbook.Path & "\"
'FILENAMEは、ワイルドカードが使えます。
"スペースがなければ、FILENAMEの前後のQT は、いらないです。
ret = Shell("CMD /C" & Cmd & " " & SEARCHWD & " " & QT & FILENAME & QT & " > " & QT & OutDir & OUTFNAME & QT)
それを、テキスト出力して、ファイル名と行数が出てきますから、それをExcelで拾いだせばよいと思います。ただし、Win9x 系は #6のvenzoさんのFind ですが、正規表現が機能には含まれません。また、Cmd は、Command.com に換わります。
>失礼ですが、プロの方ではありませんか?
メインフレームのプロ(SE)です。
PC、エクセル、VBAは独学で、これで食っていける技能はありません。
現在の職場には最近配属されたばかりで、非常にセキュリティに厳しいところです。
守秘義務があるので詳しいことは言えませんが、企業の置かれた社会的立場からやむを得ない措置だと思っています。
メインフレームが自由に使えるなら、パワーのあるマシンですべてやってしまいますが、メインフレームの使用もかなり制限されています。
PCの使用もかなり制限されていますが、幸いVBAだけは自由に使える環境です。
そこでこれを活用して、仕事を効率アップを考えたわけです。
実はこの質問に対する回答はNo.1の方で解決済みですが、他にも良い方法がないかと締め切りませんでした。
皆様から色々ご助言いただきありがとうございました。
No.6
- 回答日時:
>使いたいのは山々ですが、職場はセキュリティが厳重で外部プログラム(grepなど)のインストールは一切できません。
忘れてましたが、widows標準で、findと言うコマンドがあります。
私は使ったこと無いのですが、これが使えるかもしれませんね。
以下findのヘルプ
>find /?
ファイル (複数可) 内のテキスト文字列を検索します。
FIND [/V] [/C] [/N] [/I] [/OFF[LINE]] "文字列" [[ドライブ:][パス]ファイル名[...]
]
/V 指定した文字列を含まない行をすべて表示します。
/C 指定した文字列を含む行の数だけを表示します。
/N 行番号を表示します。
/I 大文字と小文字の区別をしないで検索します。
/OFF[LINE] オフライン属性が設定されたファイルをスキップしません。
"文字列" 検索する文字列を指定します。
[ドライブ:][パス]ファイル名
検索するファイル (複数可) を指定します。
パスが指定されていないときは、プロンプトで入力されたテキストまた
は別のコマンドからパイプ処理で渡されたテキストを検索します。
No.4
- 回答日時:
こんばんは。
#3のWendy02です。>使いたいのは山々ですが、職場のセキュリティが厳重で所定のプログラム以外は一切インストール・実行できません。
私も、仕事でHDDの文書検索はしますが、VBAは、実際の仕事では使いません。失礼かもしれませんが、それは、質問者さん個人の問題ではなくて、会社の生産性の問題です。セキュリティがどうこうの問題じゃないのですけれどね・・・。もし企業だったら、この程度の問題に対応できないようなら、どうしようもないと思います。まあ、自分の置かれた立場の問題もありますから、場合によっては、最初から最後まで黙して語らずということもありますけれど。
ただ、もう一度、ご質問を最初から読みましたが、「行数の判定」ということでしょうか?「行数の判定」だけだったら、正規表現などいりませんよ。
単に、ファイルを開いて、ファイルをAppendモードで開いて、その最後の行を取ればよいです。FILENAME は、Dir のループで入れるなりしてください。
Set objFs = CreateObject("Scripting.FileSystemObject")
Set objText = objFs.OpenTextfile(FILENAME, 8) 'Append モード
MsgBox objText.Line
objText.Close
Set objFs =Nothing
それに、文字列検索だったら、Grepの代わりに、FindStr を使えばよいです。
ただ、Unix 系ツールの方がずっと楽なことは言うまでもないです。
#1のお礼の
>知りたいのは全行数ではなく、該当文字列のあった行です。
ご質問の趣旨が、良く分かりません。
この回答への補足
回答ありがとうございます。
提示していただいたVBAはテキストファイルの行数を表示するものですね。
私が知りたいのは、やはり次の通りです。
>知りたいのは全行数ではなく、該当文字列のあった行です。(先頭から何ライン目か)
>ご質問の趣旨が、良く分かりません。
質問が言葉足らずだったかも知れません。
具体的には、テキストファイルの中身はプログラムのソースコードです。
やりたいことは以下の通りです。
数千本のプログラムソースコード(即ちテキストファイル)があります。(既に存在しています)
システム開発は標準化されていて、すべてのプログラムで項目名は統一されています。
システムメンテがある項目に対して発生した場合、対応する可能性のあるプログラムと使用されている個所を特定せねばなりません。
全ソースコードを調べ、その項目名が使われるプログラム名(即ちファイル名)とその個所(何ライン目)の一覧表を作成する必要があります。
以上ですが、お分かりいただけましたでしょうか。
No.3
- 回答日時:
こんにちは。
それは、Namazu とか、専門システムを使ったほうが早いです。
それに、その作業のことを、KeyWord In Context いわゆる KWIC といいます。専用ツールを使ったほうが良いです。例えば、コンコーダンスを作成する時や、大学などで文献検索に使うシステム・ツールです。Grep(GNUに限ります)も同じUnix系のツールですが、それをさらに文献検索用に発展させたものです。
回答ありがとうございます。
使いたいのは山々ですが、職場のセキュリティが厳重で所定のプログラム以外は一切インストール・実行できません。
使えるのはOfficeくらいなものです。インターネットにもアクセスできません。
No.2
- 回答日時:
速さにこだわるなら、外部プログラム(grepなど)で検索する方が良いかと思います。
Shell "cmd.exe /C ""grep.exe >search.log"""
検索結果をリダイレクトでファイルにして、それを解析する。
速さは、エクセルVBA(インタプリタ)とは比べものにならないと思いますよ。
コマンドライン用の検索プログラムは"grep"が有名です。
UNIX系のコマンドの移植なので、幾つかバージョンが有ったり、同名の類似品があったりします。
http://www.vector.co.jp/soft/winnt/util/se365621 …
http://www.vector.co.jp/soft/win95/util/se015011 …
grep以外でもフリーのものはあると思うので、使いやすそうなものを探してみてはいかがでしょう。
回答ありがとうございます。
使いたいのは山々ですが、職場はセキュリティが厳重で外部プログラム(grepなど)のインストールは一切できません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- Excel(エクセル) エクセル関数の変わった使い方 3 2022/05/13 17:12
- Visual Basic(VBA) VBA初心者です 検索した数字の行に色をつける 5 2023/02/13 14:22
- Java Java 南京錠 2 2023/02/04 11:46
- フリーソフト テキストファイル内を検索したい 1 2022/06/01 08:33
- Visual Basic(VBA) VBAで、特定の文字より後を削除して残った数値を文字列に変換と特定の文字より前も削除したい 3 2022/04/15 19:21
- Excel(エクセル) Excelでの検索結果を含む行だけを表示させたい 5 2023/03/10 17:08
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
- Excel(エクセル) capeofdragonと申します Excel2016を使っておりまして 半角又は全角の任意文字列が 2 2022/10/31 13:51
- Visual Basic(VBA) Vbaで数式をポーランド記法に変換するコードを作って実行しようとするとフリーズします。 1 2022/05/24 17:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルでアルファベットか数...
-
文字列からタブコードを取り除...
-
EXCELで=より左の文字を一括で...
-
住所などの中から漢数字だけを...
-
文字列を見やすくする場合
-
アクセスで特定の数字以外(複...
-
VBでの文字列操作 難技
-
“丸(〇/○/◯)”に似た文字…
-
リストボックスの文字列の取得
-
文字列から文字列を検索するプ...
-
Excelで指数表現しないようにす...
-
googleスプレッドシートでカッ...
-
VBAでの Replace関数で、ワイル...
-
CVSファイルをエクセルブッ...
-
textboxユーザーコントロールの...
-
Excelで3E8を3.00E+8にしない方...
-
OnTime 使用時のプロシージャへ...
-
VBA2005 16進を2桁で表示したい。
-
PS4コントローラーをPCでゲーム...
-
4Kの外部モニターに出力すると...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルでアルファベットか数...
-
EXCELで=より左の文字を一括で...
-
文字列からタブコードを取り除...
-
VBAでの Replace関数で、ワイル...
-
エクセルで文字列をtxtファイル...
-
【Excel VBA】複数ある特定の文...
-
エクセル 数値データを桁をそ...
-
Excelで3E8を3.00E+8にしない方...
-
VBA2005 16進を2桁で表示したい。
-
エクセルで文字列の最大値を抽...
-
同一セル内に関数と文字列を同...
-
Left関数とRight関数を合わせた...
-
Excelで指数表現しないようにす...
-
MS SQLServer のSQLで文字列の...
-
VBの「As String * 128」とは?
-
エクセルでセル内の文字列の最...
-
ORCLEでの小数の表示方法の変更...
-
bashスクリプトでの文字列から...
-
LEFT関数で文字数を指定しない...
-
アクセスで特定の数字以外(複...
おすすめ情報