[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『vba:特定列の文字列を数値化』(くろたろう)
winXP/SP3 Excel2007
特定列の文字列を数値化しています。 今は行ごとにループさせて、欲しい結果は得ていますが 40程度のファイルを対象としている為、(本当に多少ですが)計算に時間がかかります。 このループ部分を配列とかresizeを使うと早くなるのかな? とは思うのですが有用な方法や、記述の仕方がわかりません。
現在は使用に問題ない程度ですが、ファイル数が多くなった時の為にも 処理の早い記述をご教示いただけないでしょうか。 もしかしたら単に、ファイルを開くのに時間がかかってる気もしますが…
どうぞ、よろしくお願いいたします。
元データ:ACCESSからのエクスポートデータ (小数点以下が削られる為、文字列にしています)
対象列:x列 金額 -248.2661 -198.6828 -6.2067 8.9515 …といった、ランダムな数字が入っています。
現在のコード
Sub M_金額数値化() Application.ScreenUpdating = False Application.DisplayAlerts = False
Dim maxrow As Long Dim tgtCol As Long Dim i As Long Dim myFolder As String, myFindFile As String
myFolder = "I:\test\" 'フォルダのパス tgtCol = 24 '金額項目の列番号
myFindFile = Dir(myFolder & "*.xls") While myFindFile <> "" With Workbooks.Open(myFolder & myFindFile).Sheets(1) maxrow = .Cells(.Rows.Count, tgtCol).End(xlUp).Row .Columns(tgtCol).NumberFormatLocal = "G/標準" 'ここから For i = 2 To maxrow .Cells(i, tgtCol).Value = Val(.Cells(i, tgtCol).Value) Next i 'この部分の処理 ActiveWorkbook.Save ActiveWindow.Close End With myFindFile = Dir Wend
Application.ScreenUpdating = True Application.DisplayAlerts = True
MsgBox ("終わったよ") End Sub
方法は色々あるかもしれないけれども、 データ区切り位置で列まるごと処理、とか、 数値「1」をコピーして形式選択貼り付けで、乗算で対象範囲に貼り付けとか。 (みやほりん)(-_∂)b
みやほりんさん、ありがとうございます。 試したところ、以下の結果でした。
ループ 11.4375 区切り位置 11.21875 貼りつけ 12.10156
やはりファイルを開くのが重いのですね… 今回はデータ量が多くはないのでループとそれ程差が出なかったですが 1ファイルのデータ量が多いともっと変わってきそうです。
一応、後学の為に他の方法も試したいと思いますので なにかアイデアがありましたら引き続きお願いいたします。 (くろたろう)
> 一応、後学の為に他の方法も試したいと思いますので > なにかアイデアがありましたら引き続きお願いいたします。
Dim x With .Range(.Cells(2,tgtCol), .Cells(Rows.Count,tgtCol).End(xlUp)) x = .Address .Value = Evaluate("if(" & x & "<>""""," & x & "*1,"""")") End With とか (seiya)
seiyaさん、ありがとうございます。 これは範囲一括で対象に出来る書き方なんですね。勉強になります。
「Evaluate」を調べたところ、「ワークシート関数名を文字列で指定して呼び出す」と 書かれていて、if文を呼んでいるためセルには関数文が入るのかな?と思ったんですが 値が入っていて不思議でした。 計算式を指定して、その演算結果を返すことが出来るんですね。 便利です。
お二方ともありがとうございました! (くろたろう)
Evaluate 関数は 2次元配列も受け付けます。 式が、配列数式の形式であれば(全てではありません)その結果を 2次元配列で返します。
sample dim x as string, y as variant With .Range(.Cells(2,tgtCol), .Cells(Rows.Count,tgtCol).End(xlUp)) x = .Address y = Evaluate("if(" & x & "<>""""," & x & "*1,"""")") '<- 2次元配列 .value = y '<- 2次元配列のデータをDump End With (seiya)
あ、配列の中味をウォッチウィンドウで見られないな〜と思ってましたが 変数に入れちゃえばいいんですね。^^ これはソートなんかにも使えそうですね。 (あれ?無理かしら…)
*1を、セルを使わずコード内で完結出来きる方法を知りたいと思っていたので 今回勉強になりました。 応用できる様に、使用法を確認しておきます。 ありがとうございます! (くろたろう)
参考程度に (seiya)
seiyaさん> 当時このスレ見てました! 当然ちんぷんかんぷんでしたが 今、実行しながら読んだら理解できました!
ちなみにソートに利用出来るかしら、と調べたら 「RangeオブジェクトのSortメソッド」ってのが用意されてたので そっちで完結してました。 (くろたろう@目を通してても身になってない…)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.