アプリ版:「スタンプのみでお礼する」機能のリリースについて

VBAに関する質問です。

複数のテキストファイルを読み込んで
指定した文字列を別の文字列に検索・置換してくれるプログラムを作りたいと考えています。

これをするためには一度

Set MyTxt = FSO.OpenTextFile(StrPath, 1)

Do While MyTxt.AtEndOfStream = False

hairetu(xxx) = MyTxt.ReadLine

loop

のようにしてテキストデータを全て配列に読み込み、

Replace関数で一つずつ検索・置換した後に


Open StrPath For Output As #1

Print #1, hairetu(xxx)


のようにしてファイルを出力し直すしかないですか?

配列に読み込まずに
既存のファイルを直接編集する方法を教えてください。

A 回答 (9件)

1行でも同じです。



「1行」というのは、「改行文字」という特殊な文字を区切りに使っているもので、コンピュータにとっては、他の文字と違いはありません。

「行で探す」というのは「改行文字の数で探す」ことになります。
文字列で探すのと、ほとんど同じことです。



バイト数が置換の前後で同じなら、方法は無いわけではありません
(MODE BINARY ACCESS READ WRITE でOPEN→SEEKで書き換える位置へ移動)
ですが、プログラムの難易度を考えると、現在の方法より優れている、とは言えません。



もし、Excelでやらなければならない理由が無いのなら、他の方法を使うのが楽です。
例えば、テキストエディタの「grep置換」等と呼ばれる機能を使うとか。
UNIX系OSでは標準の sed コマンドのWindows版を使うとか。

この回答への補足

これであっていますか?

もっと良い方法があれば教えてください。


Sub test78()
Dim FSO As Object, buf As String
Set FSO = CreateObject("Scripting.FileSystemObject")
''C:\Work\Sample.txtの全ての文字を読み込んで表示します
With FSO.GetFile("d:\新しいテキスト ドキュメント.txt").OpenAsTextStream
buf = .ReadAll

buf = Replace(buf, "コリアン", "ジャパニーズ")

.Close
End With
Set FSO = Nothing
StrPath = "D:\test.txt"


Open StrPath For Output As #1

Print #1, buf
Close #1



End Sub

補足日時:2015/01/01 17:29
    • good
    • 0
この回答へのお礼

ありがとうございます。

結局のところ、VBAでやるなら全てのテキストデータを一度配列に読み込ませた後に、
replace関数で全ての文字列を置換後に再度テキストデータとして
出力するしかないということでしょうか?

grepのソフトウェアはあるのですが
これらのソフトも同じように一度配列に書き出す方法をとっているのでしょうか?
 

お礼日時:2015/01/01 17:20

>結局のところ、VBAでやるなら全てのテキストデータを一度配列に読み込ませた後に、


>replace関数で全ての文字列を置換後に再度テキストデータとして
>出力するしかないということでしょうか?

VBAに限らず置換前と置換後のバイト数が異なるなら一度読み込んで出力し直すしかありません。
    • good
    • 1
この回答へのお礼

ありがとうございます。
 

お礼日時:2015/01/02 11:54

【補足】3行目の"ABC"を"123"に書き換えよ。



>別ファイルに出力する手段は取ってはいけない。
>ただし、1行目、2行目と順次に3行目まで読み込むのは構わない。

【答】FileSystemObjectでは不可能。

1、X行目を取得する関数を作成する。
2、X行目を直接に書き換える関数を作成する。

これなら可能です。
    • good
    • 0

> 例えば、


>
> ABC
> DEF
> GHI
> というテキストファイルがあり
>
> DEFだけをJKLに書き換えるにはどうしたら良いですか?



Excelにこだわらず、Wordでやってみるのも一案かと思います。
以下は、Wordのマクロの自動記録です。

手順は
1.変換元のファイル(test.txt)を開く
2.置換で「DEF→JKL」(全置換)
3.別名で(test_p.txt)テキスト形式で保存

…以下だけは変更してあります。
[元ファイルのあるフォルダ名]

自動保存ですが、ここまで可能です。
後は、
・オプション変換オプション
・複数ファイルのループ設定
・変換後のファイルの保存先、ファイル名
などを調整してください

Sub Macro1()
'
' Macro1 Macro
'
'
ChangeFileOpenDirectory "[元ファイルのあるフォルダ名]"
Documents.Open FileName:="test.txt", ConfirmConversions:=False, ReadOnly:= _
False, AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:= _
"", Revert:=False, WritePasswordDocument:="", WritePasswordTemplate:="", _
Format:=wdOpenFormatAuto, XMLTransform:="", Encoding:=932
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
With Selection.Find
.Text = "DEF"
.Replacement.Text = "JKL"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = False
.MatchFuzzy = False
End With
Selection.Find.Execute Replace:=wdReplaceAll
ActiveDocument.SaveAs FileName:="test_p.txt", FileFormat:=wdFormatText, _
LockComments:=False, Password:="", AddToRecentFiles:=True, WritePassword _
:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _
SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _
False, Encoding:=932, InsertLineBreaks:=False, AllowSubstitutions:=False, _
LineEnding:=wdCRLF
End Sub
    • good
    • 0

Q、検索して書き換える方はどうすれば良いでしょうか?


A、一行づつ読んだら一行づつ書き込みます。
「テキストファイルを直接置換する方法」の回答画像5
    • good
    • 1

一般的には「直接編集する」方法は無いと思ってください。




ファイルは、原稿用紙をイメージしてください。
できることは
・マスに1文字書き込む。既に書いてあるマスだったら、消しゴムで消してから書き込む
・書いてある文字を1マスずつ読む
・全体の長さを決める
だけです。
「1行読む」は「1マス読む、を改行まで繰り返す」ことです。


ABCDE のBC をb に置き換えたいとします。
ただ2マス目をbに書き換えただけだと
AbCDE
となり、Cが残ります。「取り除く」ことはできません。
そこで
 3マス目に次の文字(D)を読み込んで書く
 4マス目に次の文字(E)を読み込んで書く
 長さを4に決める
とやる必要があります。これで AbDE になります。

挿入時も同様に 長さを延す→後へずらす→空いたマスに書き込む という操作が必要です。


これを楽にやる方法の一つが、「操作が楽なものにコピーを作って、出来上がったら元に戻す」というものです。
その実例の一つが「操作が楽な文字列の配列にコピーを作って、出来上がったものを元のファイルに書き出す」という今のやりかたです。
    • good
    • 0
この回答へのお礼

ファイルまるごと直接編集は無理だとして
一行ごとに直接編集は可能ですか?

例えば、

ABC
DEF
GHI
というテキストファイルがあり

DEFだけをJKLに書き換えるにはどうしたら良いですか?

お礼日時:2015/01/01 15:26

VBAというからにはエクセルあたりを使うわけですよね?


であれば配列とあわせて読み込んだ行をセルに表示して
目に見えるような状態にするというのも1つの方法です
シートをわけることでBefore・Afterのような
プレビューも実装することができますし
保存するコードを書く時も簡単に

ActiveWorkbook.SaveAs Filename:="ファイル名", FileFormat:=xlText

みたいにできます
以上参考までに・・・
    • good
    • 0

「DOSコマンドを利用する」という手は除外するとして・・・。

ファイルを一行づつ読み込むって手はあります。次は、私が1998年頃にマイサイトにアップした FileRead関数です。

207: FileRead関数: ファイルの各行を順次に読み込みます。

Public Function FileRaed(ByVal FileName As String) As String
On Error GoTo Err_FileRead
  Static isOpen AS Boolean
  Static fso  As FileSystemObject
  Static fil  AS File
  Static txs  As TextStream
  
  If Not isOpen Then
    isOpen = True
    Set fso = New FileSystemObject
    Set fil = fso.GetFile(FileName)
    Set txs = fil.OpenAsTextStream(ForReading, TristateUseDefault)
  End If
  FileRead = IIf(fil.Name = FileName, txs.ReadLine, "")
Exit_FileRead:
  If Len(FileRaed) = 0 Then
    isOpen = False
    Set txs = Nothing
    Set fil = Nothing
    Set fso = Nothing
  End If
  Exit Function
Err_FileRead:
  MsgBox Err.Description & "(FileRead)", vbExclamation, " 関数エラーメッセージ"
  Resume Exit_FileRead
End Function

? FileWrite("Test.txt", "1: A" & Chr$(13) & Chr$(10) & "2: B" & Chr$(13) & Chr$(10))
True
? FileRead("Test.txt")
1: A
? FileRead("Test.txt")
2: B
? FileRead("Test.txt")

 FileRead関数を使っての順次読み込みを中止する場合には FileRead("") とファイル名にヌル値をセットします。
    • good
    • 0
この回答へのお礼

読み込む方は分かったのですが
検索して書き換える方はどうすれば良いでしょうか?
 

お礼日時:2015/01/01 14:57
    • good
    • 1

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

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