Excel (VBA) |
![]() ![]() |
(指定なし : 指定なし)
インデックスが有効範囲にありませんのエラーについて
投稿日時: 22/04/16 18:15:49
投稿者: TATSUYA.ich
|
---|---|
|
![]() |
投稿日時: 22/04/16 19:58:49
投稿者: TATSUYA.ich
|
---|---|
WinArrow様
|
![]() |
投稿日時: 22/04/16 20:12:10
投稿者: WinArrow
|
---|---|
通常、デバッグは、
|
![]() |
投稿日時: 22/04/16 20:30:50
投稿者: simple
|
---|---|
投稿いただいたのは、実際に動かしたものですか?
Sub test2() Dim ary As Variant ary(0, 0) = 1 End Subと同じエラーになるはずです。 理由は既に指摘いただいているとおりです。 動的配列にする手もありますが、transposeしたり面倒なので、 少し大きめの二次元の固定配列(大きさを決めたもの)を用意しておいて、 それに書き込むのが楽かもしれません。 まあ、そのあとに何をするかによりますね。 |
![]() |
投稿日時: 22/04/16 20:46:53
投稿者: simple
|
---|---|
# 横からすみません。
|
![]() |
投稿日時: 22/04/16 21:05:44
投稿者: WinArrow
|
---|---|
勝手に推測します。
|
![]() |
投稿日時: 22/04/17 08:22:04
投稿者: simple
|
---|---|
動的配列を使う例です。下記のコードを参考にしてください。
Sub test() Dim fname$ Dim ary(), tmp Dim r&, c&, k&, num& Dim buf$ fname = "test.csv" '■ パスは適宜修正のこと。 Open fname For Input As #1 Do Until EOF(1) k = k + 1 Line Input #1, buf tmp = Split(buf, ",") If k = 1 Then num = UBound(tmp) + 1 '要素の個数 '配列再定義 r = r + 1 If k = 1 Then ReDim ary(1 To num, 1 To r) Else ReDim Preserve ary(1 To num, 1 To r) End If '配列への入力 For c = 0 To UBound(tmp) ary(c + 1, r) = tmp(c) Next Loop Close #1 ary = Application.Transpose(ary) Worksheets("Sheet1").Range("A1").Resize(UBound(ary, 1), UBound(ary, 2)) = ary End Sub なお、Application.Transposeは、 行、列いずれかが2^16=65536 を超えるとエラーになることに注意してください。 # なお、既に書いたように、動的配列にするよりも、 # 少し余裕を持たせた固定配列を確保しておいて、読み込んだ行数、項目数は分かりますから、 # Worksheets("Sheet1").Range("A1").Resize(行数, 項目数) = ary # としたほうが簡単です。未使用の部分は切り捨てられますから。 ■ 上記のように、ファイルを直接開いて操作してもよいのですが、 ・項目自体にカンマが含まれているとその対応が必要 ・日本語の文字コードの問題 などの留意点があります。 Excelにはファイルを読み込むツールが既定で用意されており、 そのあたりもオプションが用意されていて柔軟です。 それらを活用したほうが、標準化されるので安定しますし、開発に関する時間節約にもなります。 一例として下記の例を挙げておきます。 Excelのバージョンが記載されていないのですが、 少し前のバージョンのものが使いやすいかもしれません。 オプション設定の「レガシーデータインポートウイザード」で 「テキストから(レガシ)」を選択すると利用できます。 (詳細はネットで、「テキストから(レガシ)」を検索してください) Sub Macro1() Dim filename As String filename = "D:\test.csv" ' ■要修正 With Worksheets("Sheet1").QueryTables.Add(Connection:= _ "TEXT;" & filename, Destination:=Range("$A$1")) 'シート、セル位置の指定可 .RefreshStyle = xlInsertDeleteCells .TextFilePlatform = 932 ' 文字コード指定 .TextFileStartRow = 1 .TextFileParseType = xlDelimited .TextFileCommaDelimiter = True .TextFileTrailingMinusNumbers = True .Refresh BackgroundQuery:=False .Delete End With End Sub (記録されたマクロには上記のほか多数のオプション指定が記載されます。 適宜捨象しましたので、なにか不都合があるかもしれません。 その場合は見直してください。 また、最後に .deleteを追加しています。) |
![]() |
投稿日時: 22/04/17 09:09:25
投稿者: simple
|
---|---|
訂正:
・ローカルウインドウで、aryはどのようなものになっているか。 配列になっているかどうかは、ローカルウインドウで一目瞭然、 大きさ(次元)、それらの要素内容も確認できます。 ・同様にtmpの内容もローカルウインドウで確認してください。 ・r1,c1の値はなんですか? ・イミディエイトウインドウで ?tmp(c1) として何が返るか確認してください。 エラーになるならなぜか、と確認していきます。 ・その値が返っているなら、 ary(r1,c1) = その値 をイミディエイトウインドウで実行してみます。どうなりますか? とまあ、こうした作業をデバッグ(作業)というわけですが、 それに使う道具や、そのやり方もひととおり確認しておいて、 いつでも使えるようにしておくとよいでしょう。 |
![]() |
投稿日時: 22/04/17 12:03:43
投稿者: TATSUYA.ich
|
---|---|
Simple様
|
![]() |
投稿日時: 22/04/17 12:35:14
投稿者: simple
|
---|---|
丁寧な返事をいただきました。
|
![]() |
投稿日時: 22/04/17 21:21:05
投稿者: TATSUYA.ich
|
---|---|
Simple様
|
![]() |
投稿日時: 22/04/17 22:07:36
投稿者: simple
|
---|---|
https://koukimra.com/archives/1365
|
![]() |
投稿日時: 22/04/17 22:20:48
投稿者: TATSUYA.ich
|
---|---|
Simple様
|
![]() |
投稿日時: 22/04/18 11:50:50
投稿者: simple
|
---|---|
説明ご苦労様でした。
引用: とのことでした。 違います。行や列の個数の話ではありません。 それで、22/04/17 22:07:36 に追加投稿しています。 やりとりを進めていただきたいと思います。 |
![]() |
投稿日時: 22/04/19 18:23:26
投稿者: WinArrow
|
---|---|
CSVデータを配列に格納する
|
![]() |
投稿日時: 22/04/19 18:39:40
投稿者: WinArrow
|
---|---|
余計な心配かもしれませんが、
|
![]() |
投稿日時: 22/04/21 18:38:01
投稿者: WinArrow
|
---|---|
CSVデータを行ごとに配列に格納し、
Sub test() Dim BUF As String, TextFile As Object, data, CNT As Long, valINFO, data2 'D:\TEST\TEST.CSV" の項目数は6、1番目と6番目を文字列にするという前提です。 With CreateObject("Scripting.FilesystemObject") Set TextFile = .OpenTextFile("D:\TEST\TEST.csv") BUF = TextFile.ReadAll '1度に全データを読み込む Set TextFile = Nothing End With data = Split(BUF, vbCrLf) '行ごとに分割して配列へ GoSub SetFIELDINFO GoSub HENKAN With ActiveSheet .Cells.EntireRow.Delete .Range("A1").Resize(UBound(data) + 1, 1).Value = data2 .UsedRange.TextToColumns _ Destination:=Range("A1"), _ DataType:=xlDelimited, _ TextQualifier:=xlDoubleQuote, _ ConsecutiveDelimiter:=False, _ Comma:=True, _ Space:=False, _ Other:=False, _ FieldInfo:=valINFO, _ TrailingMinusNumbers:=True End With Exit Sub SetFIELDINFO: Dim j As Long j = UBound(Split(data(0), ",")) ReDim valINFO(0 To j, 0 To 1) For CNT = 0 To j valINFO(CNT, 0) = CNT + 1 Select Case CNT Case 0, 5 valINFO(CNT, 1) = xlTextFormat Case Else valINFO(CNT, 1) = xlGeneralFormat End Select Next Return HENKAN: '1次元を2次元に変換 ReDim data2(1 To UBound(data) + 1, 1 To 1) For CNT = LBound(data) To UBound(data) data2(CNT + 1, 1) = data(CNT) Next Return End Sub ※1次元→2次元変換処理追加 |