Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


13557 / 13646 ツリー ←次へ | 前へ→

【4782】テキストファイルへのパッチについて あつし 03/4/7(月) 13:12 質問
【4796】Re:テキストファイルへのパッチについて こうちゃん 03/4/8(火) 9:12 発言
【4805】Re:テキストファイルへのパッチについて あつし 03/4/8(火) 13:15 お礼
【4797】Re:テキストファイルへのパッチについて ポンタ 03/4/8(火) 9:31 回答
【4820】Re:テキストファイルへのパッチについて あつし 03/4/9(水) 0:23 質問
【4822】Re:テキストファイルへのパッチについて ポンタ 03/4/9(水) 8:26 回答
【4863】Re:テキストファイルへのパッチについて あつし 03/4/11(金) 0:53 お礼
【4814】Re:テキストファイルへのパッチについて Hirofumi 03/4/8(火) 20:44 回答
【4821】Re:テキストファイルへのパッチについて あつし 03/4/9(水) 0:26 発言
【4864】Re:テキストファイルへのパッチについて あつし 03/4/11(金) 1:03 お礼

【4782】テキストファイルへのパッチについて
質問  あつし  - 03/4/7(月) 13:12 -

引用なし
パスワード
   はじめまして。あつしと申します。
つい最近こちらのページを知りまして拝見させて頂いております。
大変参考となり助かっています。ありがとうございます。
早速なのですが、どうしても分からない点がありまして質問させていただきました。

テキストファイル(固定長)を1レコードずつ読み込み、特定部分を変更する(例えば、1バイト目から8バイト目を他の文字列に置き換える)場合についてよい方法がありますでしょうか?

なお、下記のURLの内容(「別な方法」の部分)を参考とさせて頂きマクロを作成してみましたが、

Type bytBuffEmp
  bytBuff(0 To 395) As Byte
End Type

ここでTypeでユーザの型を宣言していますが、bytBuffの長さ「267」を動的に可変させたいのですが、ユーザの型を宣言する方法だと実数値または定数を指定しなければならなくなってしまうので汎用的に使えなくなってしまいます。

http://www7.ocn.ne.jp/~tllsp/tips_fileio.htm#固定長ファイルへのパッチ

みなさんにご教授を賜りたいと思います。
よろしくお願い致します。

【4796】Re:テキストファイルへのパッチについて
発言  こうちゃん E-MAIL  - 03/4/8(火) 9:12 -

引用なし
パスワード
   あつしさん、こんにちは

>Type bytBuffEmp
>  bytBuff(0 To 395) As Byte
>End Type
>
>ここでTypeでユーザの型を宣言していますが、bytBuffの長さ「267」を動的に可変させたいのですが、ユーザの型を宣言する方法だと実数値または定数を指定しなければならなくなってしまうので汎用的に使えなくなってしまいます。
>http://www7.ocn.ne.jp/~tllsp/tips_fileio.htm#固定長ファイルへのパッチ

作成されたマクロを書かれたほうがレスがつきやすいと思いますが・・

「267」というのがよくわからないのですが、上記URLを参考にしたということなので、チョッと一言。
全体をよく見ているわけではないのですが、バッファは処理するのに十分な大きさにしておいて、データを変換するときや書き込む時の大きさを動的にされたらいかがですか?

上記URLでいえばこのあたり・・

' データを変換してファイルに書き込む
strAns = Format(vntTmp, "000000")
MidB(udtStrBuff.strBuff, 154, 6) = _
StrConv(strAns, vbFromUnicode)
udtStrBuff.strBuff = _
StrConv(udtStrBuff.strBuff, vbUnicode)
Put #lngFNum2, , udtStrBuff

【4797】Re:テキストファイルへのパッチについて
回答  ポンタ  - 03/4/8(火) 9:31 -

引用なし
パスワード
   私はテキストファイルを扱うときはVBスクリプトの
TextStreamストリームオブジェクトを利用してしまうので

http://www7.ocn.ne.jp/~tllsp/tips_fileio.htm#固定長ファイルへのパッチ

とはぜんぜん違うやり方になってしまうのですが、
以下ようなコードで動くと思います。

  FileName = "C:\My Documents\Test.Txt"

を正しいファイル名に、

  Range("A1", Range("A65536").End(xlUp)).Offset(0, 1).FormulaR1C1 = _
    "=""hogehoge""&MID(R[0]C[-1],9,LEN(R[0]C[-1])-8)"

の""hogehoge""を置き換えたい文字に置き換えてお試しください。

※実行前にバックアップを取って置いてください。

Sub test()
  Dim objText As Object
  Dim FileName As String
  Dim i As Long
  FileName = "C:\My Documents\Test.Txt"
  Set objText = CreateObject("Scripting.FileSystemObject").OpenTextFile(FileName, 1)
  i = 1
  Do
    Cells(i, 1).Value = objText.ReadLine
    i = i + 1
  Loop Until objText.AtEndOfStream
  objText.Close
  Range("A1", Range("A65536").End(xlUp)).Offset(0, 1).FormulaR1C1 = _
    "=""hogehoge""&MID(R[0]C[-1],9,LEN(R[0]C[-1])-8)"
  Set objText = CreateObject("Scripting.FileSystemObject").OpenTextFile(FileName, 2)
  For i = 1 To Range("B65536").End(xlUp).Row
    objText.WriteLine (Cells(i, 2).Value)
  Next
  objText.Close
End Sub

【4805】Re:テキストファイルへのパッチについて
お礼  あつし  - 03/4/8(火) 13:15 -

引用なし
パスワード
   ▼こうちゃんさん こんにちわ。

>作成されたマクロを書かれたほうがレスがつきやすいと思いますが・・
>
>「267」というのがよくわからないのですが、上記URLを参考にしたということなので、チョッと一言。
>全体をよく見ているわけではないのですが、バッファは処理するのに十分な大きさにしておいて、データを変換するときや書き込む時の大きさを動的にされたらいかがですか?
>
>上記URLでいえばこのあたり・・
>
>' データを変換してファイルに書き込む
>strAns = Format(vntTmp, "000000")
>MidB(udtStrBuff.strBuff, 154, 6) = _
>StrConv(strAns, vbFromUnicode)
>udtStrBuff.strBuff = _
>StrConv(udtStrBuff.strBuff, vbUnicode)
>Put #lngFNum2, , udtStrBuff

早速のレスありがとうございます。
自分のマクロを添付してみようと思ったのですが、素人が組んだマクロなもので見にくかったのでサンプルとしたURLを書きました。サンプルをコピーして使ったもので。。。やはり、ソースにコメントが必要ですよね。「267」の部分は「395」の間違えです。すみません(汗)

バッファの大きさを変更してしまうと

>Put #lngFNum2, , udtStrBuff

の部分で出力先のファイルとのレングスが一致しないというエラーが発生してしまい、バッファを大きく取ることが出来ないのです。別な方法があればと思ったのですが。。。

【4814】Re:テキストファイルへのパッチについて
回答  Hirofumi E-MAIL  - 03/4/8(火) 20:44 -

引用なし
パスワード
   こんな方法も有ります
始めて作ったので上手く行くかな?
置換するファイルを別名でCopyして、そのファイルを処理しています
置換する、文字列、位置等はワークシートから読み込んでいます
読みこむシートの構成は、
Sheet1にに設定しています
Sheet1のA2に1レコードの総バイト数(改行コード分も含む)
Sheet1のA烈のA4かA5、A6と言う様に置換するレコードの位置を
Sheet1のB烈のB4かB5、B6と言う様に置換するバイト数を
Sheet1のC烈のC4かC5、C6と言う様に置換する文字列を
書き込みます

  A    B    C
1
2 160
3
4 1    12   トウキョウト
5 20   12   東京都
6

尚、このコードは1レコードづつ読み込んで処理はしていません
直接、ファイルの指定位置に指定バイト数を書き込んでいます

以下のコードを標準モジュールに記述

Option Explicit

Public Sub SDFReplace()

  Dim i As Long
  Dim j As Long
  Dim vntInFile As Variant
  Dim strOutFile As String
  Dim dfn As Integer
  Dim lngRecLen As Long
  Dim vntRepl As Variant
  Dim lngReplMax As Long
  Dim bytBuff() As Byte
  
  '置換元のファイルを選択
  vntInFile = Application.GetOpenFilename("Textファイル (*.txt), *.txt")
  If vntInFile = False Then
    Exit Sub
  End If
  'もし置換元のファイルにデータが無い場合
  If FileLen(CStr(vntInFile)) = 0 Then
    Exit Sub
  End If
  '置換元ファイル名から置換先ファイル名を作成
  strOutFile = Left(vntInFile, InStr(1, vntInFile, _
                ".", vbBinaryCompare) - 1)
  strOutFile = strOutFile & "New" & Mid(vntInFile, _
            InStr(1, vntInFile, ".", vbBinaryCompare))
  'もし、置換先ファイルが有る場合それを削除
  If Dir(strOutFile) <> "" Then
    Kill strOutFile
  End If
  '置換元を置換先名にしてコピー
  FileCopy vntInFile, strOutFile
  'Sheet1から総バイト数、置換位置、長さ、文字列を取得
  With Worksheets("Sheet1")
    '1レコードの総バイト数(改行コードも含む)を取得
    lngRecLen = Val(.Cells(2, 1).Value)
    '置換位置、長さ、文字列を取得
    vntRepl = Range(.Cells(4, 1), _
          .Cells(65536, 3).End(xlUp)).Value
  End With
  '1レコードの置換数を取得
  lngReplMax = UBound(vntRepl, 1)
  '置換文字列をユニコードから変換してフィール長に調整
  For i = 1 To lngReplMax
    vntRepl(i, 3) = FieldString(vntRepl(i, 2), vntRepl(i, 3))
  Next i
  
  '置換先ファイルをBinaryモードでOpen
  dfn = FreeFile
  Open strOutFile For Binary As dfn
  '第一レコードから最終レコードまで繰り返し
  For i = 1 To LOF(dfn) \ lngRecLen
    '置換数まで繰り返し
    For j = 1 To lngReplMax
      '置換文字列をByte配列に格納
      bytBuff = vntRepl(j, 3)
      '置換位置に出力
      Put #dfn, vntRepl(j, 1) + lngRecLen * (i - 1), bytBuff
    Next j
  Next i
  'ファイルを閉じる
  Close dfn
    
End Sub

Public Function FieldString(ByVal lngLength As Long, _
            ByVal strData As String, _
            Optional strAlign As String = "L") As String

'  Dataをフィールド長に調整

'lngLengthはフィールドの長さを半角何文字分(バイト単位)で
'strDataはデータを文字列の型で
'strAlignは左詰なら"L"で(デホルトは"L")、
'右詰なら"R"で(実際は、"L","l"以外なら可)
  
  Dim strSpace As String
  Dim i As Long
  Dim intCode As Integer
  
  '文字列を Unicode からシステムの既定のコード ページに置換します
  strData = StrConv(strData, vbFromUnicode)
  'フィールド長よりDataが長い場合、2バイト文字の処理を行います
  If LenB(strData) > lngLength Then
    strData = LeftB(strData, lngLength)
    intCode = Asc(Right$(StrConv(strData, vbUnicode), 1))
    If (0 <= intCode And intCode <= 7) _
        Or (11 <= intCode And intCode <= 12) _
        Or (14 <= intCode And intCode <= 31) _
        Or (127 <= intCode And intCode <= 159) _
        Or (224 <= intCode And intCode <= 255) Then
      strData = LeftB(strData, lngLength - 1)
    End If
  End If
  
  '長さ調整用のスペースを作成します
  If lngLength > LenB(strData) Then
    strSpace = StrConv(Space$(lngLength - LenB(strData)), _
                          vbFromUnicode)
    'Dataをフィールド長に調整します
    If strAlign = "L" Or strAlign = "l" Then
      strData = strData & strSpace
    Else
      strData = strSpace & strData
    End If
  End If
  
  FieldString = strData
  
End Function

【4820】Re:テキストファイルへのパッチについて
質問  あつし  - 03/4/9(水) 0:23 -

引用なし
パスワード
   ポンタさん、こんばんわ。
返信が遅くなってしまい申し訳ありません。
早速のレス、ありがとうございます!
確認させていただきました。

>の""hogehoge""を置き換えたい文字に置き換えてお試しください。

文字列をセットした場合からの変換は成功しました!
の部分ですが、変数からのセットは可能でしょうか?
初歩的な質問で申し訳ありませんがよろしくお願い致します。

また、その変数はbyte型で中身はバイナリ(パック形式)がセットされています。
(例:01234567が4バイトの変数に入っています)
ここ↑の部分は最初の質問に書き忘れていました。申し訳ありません。

【4821】Re:テキストファイルへのパッチについて
発言  あつし  - 03/4/9(水) 0:26 -

引用なし
パスワード
   Hirofumi さん、こんばんわ。
ありがとうございます。この方法で試して見ます。

【4822】Re:テキストファイルへのパッチについて
回答  ポンタ  - 03/4/9(水) 8:26 -

引用なし
パスワード
   他の方からレスがついているようなので、
そちらをお使いになったほうが良さそうですが、
一応載せときます。

Sub test()
  Dim objText As Object
  Dim FileName As String
  Dim MyReplace As String
  Dim i As Long
  FileName = "C:\My Documents\Test.Txt"
  Set objText = CreateObject("Scripting.FileSystemObject").OpenTextFile(FileName, 1)
  i = 1
  Do
    Cells(i, 1).Value = objText.ReadLine
    i = i + 1
  Loop Until objText.AtEndOfStream
  objText.Close
  MyReplace = "hogehoge"
  Range("A1", Range("A65536").End(xlUp)).Offset(0, 1).FormulaR1C1 = _
    "=""" & MyReplace & """&MID(R[0]C[-1],9,LEN(R[0]C[-1])-8)"
  Set objText = CreateObject("Scripting.FileSystemObject").OpenTextFile(FileName, 2)
  For i = 1 To Range("B65536").End(xlUp).Row
    objText.WriteLine (Cells(i, 2).Value)
  Next
  objText.Close
End Sub

【4863】Re:テキストファイルへのパッチについて
お礼  あつし  - 03/4/11(金) 0:53 -

引用なし
パスワード
   返信が遅くなってしまい申し訳ありません。
無事動作確認することが出来ました!
ありがとうございました。
また何かありましたら、よろしくお願い致します。

【4864】Re:テキストファイルへのパッチについて
お礼  あつし  - 03/4/11(金) 1:03 -

引用なし
パスワード
   Hirofumi さん、こんばんわ。
お忙しいところ、大作を作っていただきありがとうございました。
返信が遅くなって申し訳ありません。実際に動作させてみました。
汎用的なツールとなっているので、大変助かります。
参考にさせていただきました。
また何かありましたら、よろしくお願い致します。
本当にありがとうございました。

13557 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free