人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

ExcelVBAでの全角と半角が混在するテキストファイル(改行無しで10MBと大容量)を読み込み、指定バイト数で区切りを入れるという文字列を処理します。
例)文字列:あいうえおabcdかきくけこ012345、指定バイト数:10
あいうえお
abcdかきく
けこ012345
LenBやMidBの動きがVBAとワークシート関数で異なるため、下記処理が必要となり、これを通した場合、処理がものすごく遅くなります。
LenB(StrConv(str, vbFromUnicode))
StrConv(MidB(StrConv(str, vbFromUnicode), start, length), vbUnicode)
参考:http://makotowatana.ld.infoseek.co.jp/vba_character.html#bite
この処理遅延は何とか回避できないのでしょうか?全角半角が混在しているテキストをVBAで処理する場合の、速度面を重視した文字列処理記述方法をご提示下さい。
http://q.hatena.ne.jp/1240918358
と同じ処理を、全角半角でも速くやるには、という質問です。
(VBAでのテクニックが知りたいので、同じ処理を別の言語でする、という回避方法はなしでお願いします。Excelのバージョンは2000-2007です。)

●質問者: smileless
●カテゴリ:ビジネス・経営 コンピュータ
✍キーワード:Excel STR VBA あいうえお テキスト
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● ふるるP
●23ポイント

一部分だけでなくて、関係するところをまとめて質問すると良いです。

投稿された処理内容は、多分ループ内での処理だと思います。

全体のうちの部分部分の文字列をその少ない文字列ごとにstrConvで変換しているので、処理が無駄です。全体を一括で変換するようにして、処理の回数を減らしましょう。

また、文字数が多い場合、前もってバッファを用意し、MidBステートメント(※注 関数じゃないですよ)で変換するのが処理を早くする方法です。

しかし、もともとがテキストファイルであるなら、Binaryで開いて、指定バイト数分読み込み、区切り文字(改行コードとか)を追加して別ファイルに出力していく、

最後までデータを別ファイルに出力し終わったら、元のファイルを削除して、作っておいた別ファイルの名前を元のファイル名に変更する。というロジックのほうが圧倒的に速いでしょう。

urlはダミーです。

http://www


2 ● jccrh1
●23ポイント

前回の回答に近いのですが、読み取り時ANSIIで取得し、StrConvでUNICODEに変換しています。

処理時間は7MBで約6秒でした。

Option Explicit
Sub 入力処理()
 Const レコード長 = 500
 Dim レコード数 As Long
 Dim レコード(レコード長 - 1) As Byte
 Dim I As Long
 Dim 進捗率 As Integer
 
 Application.ScreenUpdating = False
 Open ThisWorkbook.Path & "\TEST.TXT" For Binary As #1
 レコード数 = (LOF(1) / レコード長)
 
 For I = 1 To レコード数
 進捗率 = I * 10 / レコード数
 Application.StatusBar = String(進捗率, "■") & String(10 - 進捗率, "□")
 Get #1, , レコード
 Range("A1").Offset(I - 1).NumberFormatLocal = "@"
 Range("A1").Offset(I - 1).Value = StrConv(レコード, vbUnicode)
 Next I
 Close
 Application.StatusBar = False
 Application.ScreenUpdating = True
End Sub

注)全角が500バイトの切れ目にならいとしています。

ダミー

http://q.hatena.ne.jp/1241755947


3 ● AZUY
●22ポイント

テキストファイルの中がSJISだと仮定してですが

Byte配列をつかって処理すると速いです。

http://q.hatena.ne.jp/answer


4 ● mj99
●22ポイント

2バイト文字が割れないよう考慮してみました。

Excel2003で1秒切れます(PCの性能によりますが)

Public Sub test1()
 
 Const fileName As String = "D:\a.txt"
 Const readCount As Long = 500
 Const bufEnd As Long = readCount - 1
 Const rowMax As Long = 65536
 
 Dim i As Long
 Dim rg As Range
 Dim bf() As Byte
 Dim cx As Variant
 
 Debug.Print Now()
 
 Application.ScreenUpdating = False
 
 'データを貼り付ける範囲
 Set rg = Worksheets(1).Range("A1:A" & rowMax)
 rg.Clear
 rg.NumberFormatLocal = "@"
 
 '2次元配列を作る
 cx = rg
 
 'ファイル読み込み
 With CreateObject("ADODB.Stream")
 .Type = 1 'adTypeBinary
 .Open
 .LoadFromFile fileName
 
 i = 1
 Do Until .EOS Or i > rowMax
 
 bf = .Read(readCount)
 
 '2バイト文字の割れ目調整(ファイルがShift_JISであると決め付け)
 If UBound(bf) = bufEnd Then
 If (bf(bufEnd) >= &H81 And bf(bufEnd) <= &H9F) Or (bf(bufEnd) >= &HE0 And bf(bufEnd) <= &HFF) Then
 ReDim Preserve bf(bufEnd - 1) As Byte '読み込んだバイト列の末尾を潰す
 .Position = .Position - 1 'ファイルポインタを1バイト前へ
 End If
 End If
 
 cx(i, 1) = StrConv(bf, vbUnicode)
 i = i + 1
 Loop
 .Close
 End With
 
 '配列をセルに移す
 rg = cx
 
 Debug.Print Now()

End Sub


----

おまけ。個別に時間計測。

・セルに値を入れる時間

・StrConvの処理時間

Public Sub test2()
 
 '500バイトの文字列を65536個のセルに入れる処理
 Const dataCount As Long = 500
 Const rowMax As Long = 65536
 
 Dim i As Long
 Dim rg As Range
 Dim bf As String
 Dim cx As Variant
 
 Debug.Print Now()
 
 Application.ScreenUpdating = False
 
 Set rg = Worksheets(1).Range("A1:A" & rowMax)
 rg.Clear
 rg.NumberFormatLocal = "@"
 
 cx = rg
 
 bf = String(dataCount, "a")
 For i = 1 To rowMax
 cx(i, 1) = bf
 Next
 
 rg = cx
 
 Debug.Print Now()

End Sub

Public Sub test3()
 
 '500バイトを65536回StrConvで変換する処理
 Const dataCount As Long = 500
 Const rowMax As Long = 65536
 
 Dim i As Long
 Dim bf() As Byte
 Dim bf2 As String
 
 Debug.Print Now()
 
 bf = StrConv(String(dataCount, "a"), vbFromUnicode)
 For i = 1 To rowMax
 bf2 = StrConv(bf, vbUnicode)
 Next
 
 Debug.Print Now()

End Sub

http://q.hatena.ne.jp/1241755947

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ