EXCEL2003を使用してます

VBAでCSVファイルを読み込み
セルに書き込む動きを作成しました

当初、FOR~NEXTでまわしてセルに一つ一つ書き込んで
ましたが、速度向上の為

配列に格納して貼り付けをしています
例:

Dim aryStrings() As String
ReDim aryStrings(16)
'デリミタ[,]でデータ分割
aryStrings = Split(rec, ",")

.Range(Cells(1, 3), Cells(1, 18)) = aryStrings()

EXCEL上では数値として扱いたいのですが
CSV読み込み時に文字列として扱うため配列は
String型になっております
※セルの書式設定は数値型を設定済

配列貼り付け後確認するともちろんですが文字列として張り付いてます
(該当セルで編集+ENTERでEXCELが数値に変換してくれますが)

下記の3つの方法で可能な事はありますか?
(1)CSV読み込み時に数値に変換して配列に格納
(2)配列を一気に数値型に変換
(3)文字列配列を数値型に変換しながらEXCELに一気に
 配列貼り付け

ご存知の方、いらっしゃいましたらアドバイスお願い致します

このQ&Aに関連する最新のQ&A

A 回答 (3件)

一例ですが、Clipboard経由で書き出す方法もありかも。

(カンマ区切りの状態にもよりますが)

'Microsoft Forms 2.0 Object Libraryを参照設定
Dim n As Long
Dim buf

n = FreeFile
Open "D:\test.csv" For Input As #n
buf = StrConv(InputB(LOF(n), #n), vbUnicode)
Close #n
With New DataObject
.SetText Replace$(buf, ",", vbTab)
.PutInClipboard
End With
ActiveSheet.Paste Range("A1")

#データ量が多い場合はReplace関数ではなく"VBScript.RegExp"のReplaceメソッドを使ったほうが良いです。
    • good
    • 0

実行速度のことを言われると判断に困るが


#1と似ているが,
全セル数値文字が確実なら
Sub Macro2()
   Range("F1")=1
Range("F1").Select
Selection.Copy
Range("A1:C3").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlMultiply, _
SkipBlanks:=False, Transpose:=False
End Sub
マクロの記録で出来たもの。
形式を選択して貼り付けー乗算
範囲Range("A1:C3").Selectの範囲の一般化は色々ある。UsedRangeを使うとか。略。
ーー
VALしてセルに代入する方式では、
ScreenUpdatingをFalseにしても、そんなに時間がかかりますか?
時間がかかるのは、ディスクを読むCSVファイルの入力処理時間ではないのかな。
==
Sub test01()
Close #1
Dim aryString As Variant
Open "test01.csv" For Input As #1
i = 1
While Not EOF(1)
Line Input #1, rec
'MsgBox rec
aryStrings = Split(rec, ",")
ActiveSheet.Range(Cells(i, 3), Cells(i, 18)) = aryStrings
i = i + 1
Wend
Close #1
MsgBox VarType(Range("C1"))
End Sub
のように質問のコードと同じことはバリアント変数でも出来る。
しかし、やってみると
= Val(aryStrings)
=Val(aryStrings)
はできないようだ。
どちらかの段階で個別セルごとにValをかけないとダメでしょう。
ForNextのループなどを使うことになろう。
==
実際に処理時間がどれが短いかやってみないとわからないだろう。
我々レベルでコードを見て計算出来る理論など持ち合わせている人は居ないだろう。2,3の方法で試行錯誤せよということ。
==
ScreenUpdatingをFalseは必須。
    • good
    • 0

ひとつの方法として、エクセルへ全て書き込んだ後


書き込まれた範囲を選択して、コピーし
同じ範囲に「形式選択して貼り付け」の「値のみ」で貼り付けてもOKだと思いますが。

簡単には下記のようにします。
 
ActiveSheet.UsedRange.Value = ActiveSheet.UsedRange.Value

Sheets("Sheet3").UsedRange.Value = Sheets("Sheet3").UsedRange.Value

 
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qエクセルへのデータの貼付時に書式が反映されない!

お世話になります。

VBでエクセルにデータを貼り付ける処理があるのですが、
エクセルの書式設定(数値で小数点第3位まで表示)が反映されず、そのままの値が文字列として表示されてしまいます。

そのセルをダブルクリックすると書式が反映されます。

貼り付ける時はパフォーマンスを考慮して、下記のように一括で貼り付
けるようにしています。
「m_xlSheet.Range("A" + CStr(lngRows) + ":U" + CStr(lngRows)).Value = strValue」
何かよい方法をご存知でしたら、教えて下さい。

環境:VB6(SP6)、エクセル2000

Aベストアンサー

こんにちは。KenKen_SP です。

> m_xlSheet.Range("A" + CStr(lngRows) + ":U" + CStr(lngRows)).Value = strValue

変数 strValue が String型配列になっているからですね。恐らく、VB の自動
キャスト機能が原因です。

オートメーションのコードを書くのは面倒なので、Excel VBA でサンプルを
書いておきます。変数の型の違いでセルへ転記がどのように違うかを確認して
下さい。

Sub Sample1()

  ' 文字列として数字が転記される例
  
  Dim Buf() As String '<-- 文字列型変数が原因
  
  ReDim Buf(1 To 5, 1 To 5)
  For i = 1 To 5
    For j = 1 To 5
      ' 数値が文字列にキャストされる
      Buf(i, j) = 12345
    Next j
  Next i
  Range("A1:E5").Value = Buf

End Sub

ではどうするかといえば、配列の型を Variant にしてしまうのが一番
簡単です。

Sub Sample2()

  ' 対応策
  
  Dim Buf() As Variant '<-- バリアント型にする
  
  ReDim Buf(1 To 5, 1 To 5)
  For i = 1 To 5
    For j = 1 To 5
      Buf(i, j) = 12345
    Next j
  Next i
  Range("A1:E5").Value = Buf

End Sub

こんにちは。KenKen_SP です。

> m_xlSheet.Range("A" + CStr(lngRows) + ":U" + CStr(lngRows)).Value = strValue

変数 strValue が String型配列になっているからですね。恐らく、VB の自動
キャスト機能が原因です。

オートメーションのコードを書くのは面倒なので、Excel VBA でサンプルを
書いておきます。変数の型の違いでセルへ転記がどのように違うかを確認して
下さい。

Sub Sample1()

  ' 文字列として数字が転記される例
  
  Dim Buf() As String '<-- 文字列型変数が原因
...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

QExcelVBAでデータを一括してセルに貼り付ける

こんばんは

ExcelVBAで教えてください。
配列のデータをセルに貼り付ける方法です。
一つ一つ行う方法は解ります。
しかし、これでは件数が多いと時間がかかってしまいます。
まとめて貼り付ける方法を教えてください。
例えば次のように100列1000行のデータのとき、一つ一つでは10万回も貼り付けることになります。
これを1行単位で1000回とか全部まとめて1回とかでできないでしょうか。
配列データを用意する都合で1行単位もお願いします。


For Row = 1 To 1000
For Column = 1 To 100
Cells(Row, Column).Value = 配列(Row - 1, Column - 1)
Next
Next

Aベストアンサー

http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_070_08.html
を参考にしてください。

QEXCELファイルのカレントフォルダを取得するには?

EXCELファイルのカレントフォルダを取得するには?

C:\経理\予算.xls

D:\2005年度\予算.xls

EXCEL97ファイルがあります。

VBAで
  カレントフォルダ名
(C:\経理\,D:\2005年度\)
を取得する事は可能でしょうか?

CURDIRでは上手い方法が見つかりませんでした。

Aベストアンサー

こんばんは。
Excel97 でも、同じですね。以下で試してみてください。

Sub test()
'このブックのパス
a = ThisWorkbook.Path
'アクティブブックのパス
b = ActiveWorkbook.Path
'Excelで設定されたデフォルトパス
c = Application.DefaultFilePath
'カレントディレクトリ
d = CurDir
MsgBox "このブックのパス   : " & a & Chr(13) & _
   "アクティブブックのパス: " & b & Chr(13) & _
   "デフォルトパス    : " & c & Chr(13) & _
   "カレントディレクトリ : " & d & Chr(13)
End Sub

QRange("A1")⇔cells(1,1)の変換。

EXCELのマクロについて質問します。
Range("A1")⇒(1,1)
cells(1,1)⇒("A1")
に一発変換する方法を教えて下さい。
時間があるかた宜しくお願いします。

Aベストアンサー

こんなのでよろしいでしょうか?
range("A1") → Range("A1").Row & "," & Range("A1").Column
cells(1,1) → Cells(1, 1).Address(False, False)
()や""は付けていません

QEXCELのVBAでのSelectとActivateの違い

VBAの初心者です。
ExcelのVBAでメッセージを表示してシートを切換えるというのを作りたいのです。
見真似で作成したのが↓です。


Dim rtn As String
rtn = MsgBox("シートを切換えますか", vbYesNo, "シートの切替")
If rtn = vbYes Then
Worksheets("送付先一覧").Activate
Range("a1").Select

Else
Exit Sub
End If

動作確認はできましたが、上記の「Activate」を「Select」に変更しても特に動作異常がありません。
そこで、疑問ですが、「Activate」と「Select」ってどうやって使い分けるのでしょうか?

Aベストアンサー

こんにちは。

通常は、シートもセルも Select でよいと思います。
選択して、扱えるようにするということだと思います。

#2さんも述べておりますが、Activate って、ひとつを選ぶことですね。でも、なぜか、Activate は、ほとんど使いません。

たぶん、Select は、選択した後に、その選択したものを、そのままオブジェクトとして確保して使えるので便利だから選ばれるのかもしれません。

Select → Selection
として使えます。

Q【エクセルVBA】「インデックスが有効範囲にありません」というエラーがでます

こんにちは。VBA初心者ですが、下記コードを実行すると
エラーが出てしまいました。

シート(シート1)のセルから別シート(シート2)のセルに
値のみコピーするVBAを組んでいます。
適宜、シート1に入力したものを読みこませていきたいので
変数を使用しています。

-------------------------------------------------------------
Sub セルのコピー()

Dim X As Integer

X = 3
Y = 2
Do While Cells(X, "A").Value <> ""
Sheets("シート1").Cells(X, "A").Copy

Sheets("シート2").Activate
Sheets("シート2").Cells(Y, "F").PasteSpecial _ Paste:=xlPasteValues ⇒エラー対象
Application.CutCopyMode = False

X = X + 1
Y = Y + 1

Loop

End Sub

------------------------------------------------------------
つまり、シート1のA3セルを先頭にA4,A5,A6・・・と続くセルの値
をシート2のF2を先頭としたセル(以下、F3,F4・・・)に値のみコピー
していきたいのですが。。

実行すると「インデックスが有効範囲にありません」というエラーが
でます。デバック対象は上記、「⇒エラー対象」の構文です。

変数の設定の仕方がおかしいのでしょうか。。
ご教示のほどよろしくお願いいたします。

こんにちは。VBA初心者ですが、下記コードを実行すると
エラーが出てしまいました。

シート(シート1)のセルから別シート(シート2)のセルに
値のみコピーするVBAを組んでいます。
適宜、シート1に入力したものを読みこませていきたいので
変数を使用しています。

-------------------------------------------------------------
Sub セルのコピー()

Dim X As Integer

X = 3
Y = 2
Do While Cells(X, "A").Value <> ""
Sheets("シート1").Cells(X, "A").Copy

Sheets("シート2").Activat...続きを読む

Aベストアンサー

>Sheets("シート2").Cells(Y, "F").PasteSpecial _ Paste:=xlPasteValues ⇒エラー対象
で、「PasteSpecial _ Paste:=xlPasteValues」 の “_” を消去してください。
また、
 Sheets("シート2").Activate で "シート2" を Activate にすると、 Do Loop の頭に返ってきたとき、
 Do While Cells(X, "A").Value <> "" の Cells(X, "A") は "シート2" の Cells(X, "A") を見に行きますので、 思っているような動作はしません。
 最後の Loop の前に、 Sheets("シート1").Activate を入れるか、While の後の Cells(X, "A").Value の頭に、Sheets("シート1"). をつければ、この問題を回避することができます。

コピー先のシートは、アクティブにしなくても、ペーストする方法があります。

あなたのコードを少し変更します。

 Sub セルのコピー2()
   Dim X As Integer, Y As Integer

   X = 3
   Y = 2
   Do While Cells(X, "A").Value <> ""
     Sheets("シート1").Cells(X, "A").Copy Destination:=Sheets("シート2").Cells(Y, "F")
     X = X + 1
     Y = Y + 1
   Loop
   Application.CutCopyMode = False
 End Sub

注) 使っているブラウザの見る条件によって、「Sheets("シート1").Cells(X, "A").Copy Destination:=Sheets("シート2").Cells(Y, "F")」と「Destination:=Sheets("シート2").Cells(Y, "F")」が2行になったように見えることがあるかもしれません。 2つのコードはスペースを1つはさみ、続けて書いてください。

変更したコードの場合、"シート1" が常時表示されたままになります。

行数が200行くらいとのこと、速度を早くしたい場合は、最初に
 application.ScreenUpdating=False
最後に、
 application.ScreenUpdating=True
を加えます。

なお、シート名は "Sheet1" ですか、"シート1"ですか、どちらかに揃えましょう。 、"シート1"と、"シート2"がブックの先頭から順になっているときは、シート名を使わなくてそれぞれ Sheets(1)、Sheets(2) でもいけます。 (1)、(2) は左から 1番目のシート、2番目のシートという意味です。

試してみてください。

>Sheets("シート2").Cells(Y, "F").PasteSpecial _ Paste:=xlPasteValues ⇒エラー対象
で、「PasteSpecial _ Paste:=xlPasteValues」 の “_” を消去してください。
また、
 Sheets("シート2").Activate で "シート2" を Activate にすると、 Do Loop の頭に返ってきたとき、
 Do While Cells(X, "A").Value <> "" の Cells(X, "A") は "シート2" の Cells(X, "A") を見に行きますので、 思っているような動作はしません。
 最後の Loop の前に、 Sheets("シート1").Activate を入...続きを読む

QVB上で実行中の無限ループの止め方

今まで、CUIベースのBASICでのプログラムの経験はあるのですが
Visual系のBASICは初心者です。
原因はわかっているのでプログラムの修正はできるのですが
VB上でコンパイルして実行したときに無限ループに陥ってしまって
どうにもプログラムをとめられなくなります。
そんなことがないように、実行前に全てのプロジェクトを保存して
いますので、そんなに実害はないのですが、どうすればとめられるのでしょう・・
今現在は、タスクマネージャーから強制終了させています。

Aベストアンサー

無限ループの一番内側に
DoEvents
を入れておくと、ウィンドウ切替え->デバッガ終了操作が出来ますよ

危なそうなとこにも入れておくと、何かと安心です。

QEXCEL VBA で指定した範囲に入力があるかどうか?

こんばんは!!
EXCEL VBAを使い出して、初日からつまずいてます・・・。
みなさん、アドバイスよろしくお願いします!!

で、早速、質問なんですけど、
指定したセル範囲のいずれかに入力があるか調べたいんですけど、それができるプロパティとかってあるんでしょうか?
地道にセル毎にチェックするしかないいんでしょうか??

たとえば、範囲をA1:H1として、その範囲内のセルに何か入力があったらTrueが返ってくるとか・・・。

もし、知ってる方がいらっしゃたら教えてください!!
よろしくお願いします!!!!!

Aベストアンサー

>これは、まず範囲を選択して、入力チェック()を呼ぶことなのでしょうか
書いたモジュールは範囲が指定してあります。("A1:H11"は間違いです。質問からすると"A1:H1"です)何もしないで入力チェックを実行します。
モジュールを CountA(Selecton) に変えれば任意の選択範囲がチェックの対象になります。任意の範囲を選択して実行します。
メッセージは確認するためで、IF ・・・・ で入力有無が判定できます。

>ワークシート関数CountAってどうやったら出てくるんですか??
ついApplicationと書いてしまうんですが、『WorksheetFunction.』と打てば、候補の関数名が表示されると思います。

下記の fnc入力チェック は入力有無を返すユーザー定義関数です。
書き方の例です。分かりやすくなった?この例は引数に"A1:H1"をセットしています。任意の範囲にするには Selection.Address に変えます。

Sub 入力チェック()
  Dim 入力有無フラグ As Boolean        '入力有無の答え

  入力有無フラグ = fnc入力チェック("A1:H1")  'モジュール内でA1~H1を指定(固定)

  MsgBox 入力有無フラグ            '帰ってきた答えをメッセージボックスで確認
End Sub

'入力有無を返すユーザー定義関数
Function fnc入力チェック(checkAddress As String)
  If WorksheetFunction.CountA(Range(checkAddress)) > 0 Then
    fnc入力チェック = True
  Else
    fnc入力チェック = False
  End If
End Function

>これは、まず範囲を選択して、入力チェック()を呼ぶことなのでしょうか
書いたモジュールは範囲が指定してあります。("A1:H11"は間違いです。質問からすると"A1:H1"です)何もしないで入力チェックを実行します。
モジュールを CountA(Selecton) に変えれば任意の選択範囲がチェックの対象になります。任意の範囲を選択して実行します。
メッセージは確認するためで、IF ・・・・ で入力有無が判定できます。

>ワークシート関数CountAってどうやったら出てくるんですか??
ついApplicationと書いてし...続きを読む

QVBAにて、配列のデータを一度にシート上に貼り付ける方法

シートにデータを貼り付けるための高速化を検討しています。
現在、VBからエクセルの指定セルに直接データを書いていますが、遅くてしかたありません。
 (こんな感じです ⇒ Cell(○、□) = データ)
一応、表示更新は、止めています。(ScreenUpdatingプロパティを使っています。)

配列のデータを一度に、あるシート上に貼り付けたいのですが、ループ処理で回すしか方法がありませんか?
すいませんが、宜しくお願いします。

Aベストアンサー

3個だけの配列のサンプルですが、どうでしょう
縦に貼り付け
Sub test()
Dim a(2, 0) As Variant
a(0, 0) = "aaa"
a(1, 0) = "bbb"
a(2, 0) = "ccc"

Range("A1:A3").Value = a

End Sub

一応横の貼り付けはこうなります。
Sub test2()
Dim a(0, 2) As Variant
a(0, 0) = "aaa"
a(0, 1) = "bbb"
a(0, 2) = "ccc"

Range("A1:C1").Value = a

End Sub

配列は2次元でないと、うまくいきません。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報