Excel VBA質問箱 IV

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

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


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

【7361】2次元(多次元)配列の宣言について KAZ 03/9/3(水) 12:15 質問
【7381】Re:2次元(多次元)配列の宣言について Jカーター 03/9/3(水) 18:37 回答
【7382】Re:2次元(多次元)配列の宣言について Jカーター 03/9/3(水) 18:50 回答
【7383】Re:2次元(多次元)配列の宣言について Jカーター 03/9/3(水) 19:06 回答
【7393】Re:2次元(多次元)配列の宣言について Jaka 03/9/4(木) 9:32 回答
【7394】表現が...。 Jaka 03/9/4(木) 9:40 発言
【7420】Re:2次元(多次元)配列の宣言について Jカーター 03/9/4(木) 16:07 回答
【7433】Re:2次元(多次元)配列の宣言について KAZ 03/9/5(金) 0:01 お礼
【7438】Re:2次元(多次元)配列の宣言について Jaka 03/9/5(金) 9:15 回答

【7361】2次元(多次元)配列の宣言について
質問  KAZ  - 03/9/3(水) 12:15 -

引用なし
パスワード
   久しぶりにお世話になります。既存の配列データを保持したまま配列の添字を増やす為に
"Preserve"キーワードがありますが、次のような場合、「インデックスが有効範囲にありません」にてエラーになってしまいます。なにか良い方法はないでしょうか?

*ユーザーフォーム上の二つのテキストボックスの値を2次元配列に格納し、複数列の
リストボックスに表示させたい・・・

Dim A()

Private Sub Commanbutton1_Click()
Dim X As Integer
X = Listbox1.ListCount
Redim preserve A(X + 1 , 2) <------ ここでエラー
 A(X ,0) = TextBox1.Text
 A(X , 1) = TextBox2.Text
ListBox1.List = A
End Sub 

宜しくお願い致します。

【7381】Re:2次元(多次元)配列の宣言について
回答  Jカーター  - 03/9/3(水) 18:37 -

引用なし
パスワード
   ▼KAZ さん:
Preserveキーワードを使う場合は
2次元配列の場合は2時限目しか可変にできないようです。
対策としては
A(2, X + 1)
という感じで行列を逆に考えて配列を作り
ListBox1.Column = A
としてはどうでしょう?

違ったらすいません。

【7382】Re:2次元(多次元)配列の宣言について
回答  Jカーター  - 03/9/3(水) 18:50 -

引用なし
パスワード
   ▼KAZ さん:
よくみたらリストに追加ですか?
でしたら
AdditemとListを使えば直接できそうですが

【7383】Re:2次元(多次元)配列の宣言について
回答  Jカーター  - 03/9/3(水) 19:06 -

引用なし
パスワード
   こんばんは。
▼KAZ さん:
実際にコードにすると

Private Sub Commanbutton1_Click()
  With Me.ListBox1
    .Additem Me.TextBox1.Value
    .List(.ListCount-1,1) = Me.TextBox2.Value
  End With
End Sub 

※テストはしてません(違ったらすいません。)

【7393】Re:2次元(多次元)配列の宣言について
回答  Jaka  - 03/9/4(木) 9:32 -

引用なし
パスワード
   おはようございます。
エラーに付いては、Jカーターさんがおっしゃっていますが。

ヘルプより
メモ  動的配列でキーワード Preserve を使用する場合、最後の次元の上限値のみ変更できます。次元数は変更できません。

リストボックスは、ColumnCountが2になっているとして。
配列を1行余分に作らないと、なんかうまくいかなかった。
しかし、この方法だと配列をメモリに維持しつづけるのがちょっと気になる。
数が多くなってくるとトロくなりそう。

Dim A() As String

Private Sub CommandButton1_Click()
Dim X As Integer
X = ListBox1.ListCount
If X = 0 Then
  ReDim Preserve A(0 To 1, 0 To X + 1)
Else
  ReDim Preserve A(0 To 1, 0 To X)
  X = X - 1
End If
A(0, X) = TextBox1.Value
A(1, X) = TextBox2.Value
ListBox1.List = Application.Transpose(A)
Range("C1:D1").Value = Application.Transpose(A)
DoEvents
End Sub

これってバグ??
If X = 0 Then
  ReDim Preserve A(0 To 1, 0 To X + 1)
Else
  ReDim Preserve A(0 To 1, 0 To X)
  X = X - 1
End If
上のIF文をとって単純に下のようにした場合。
ReDim Preserve A(0 To 1, 0 To X)


メモリ無いに維持させない方法。

Private Sub CommandButton1_Click()
  Dim LtTb() As String
  LTC = ListBox1.ListCount
  ReDim LtTb(1 To LTC + 1, 1 To 2)
  If LTC <> 0 Then
    For i = 1 To LTC
      LtTb(i, 1) = ListBox1.List(i - 1, 0)
      LtTb(i, 2) = ListBox1.List(i - 1, 1)
    Next
  Else
    i = 1
  End If
  LtTb(i, 1) = TextBox1.Value
  LtTb(i, 2) = TextBox2.Value
  ListBox1.List = LtTb
  DoEvents
  Erase LtTb
End Sub

【7394】表現が...。
発言  Jaka  - 03/9/4(木) 9:40 -

引用なし
パスワード
   >数が多くなってくるとトロくなりそう。
他の作業がって事です。

【7420】Re:2次元(多次元)配列の宣言について
回答  Jカーター  - 03/9/4(木) 16:07 -

引用なし
パスワード
   こんにちは。
こんな方法もありかもしれません。
空のListBoxから始まることも考慮してます。
--------------------------------------------------------------------
Private Sub CommandButton1_Click()
  Dim VntList As Variant
  Dim VntTmp() As Variant
  
  VntList = Me.ListBox1.Column
  If IsNull(VntList) Then
    ReDim VntTmp(1, 0)
    VntList = VntTmp
  Else
    ReDim Preserve VntList(1, UBound(VntList, 2) + 1)
  End If
  VntList(0, UBound(VntList, 2)) = Me.TextBox1.Value
  VntList(1, UBound(VntList, 2)) = Me.TextBox2.Value
  Me.ListBox1.Column = VntList
End Sub
----------------------------------------------------------------------
違ったらすいません。

【7433】Re:2次元(多次元)配列の宣言について
お礼  KAZ  - 03/9/5(金) 0:01 -

引用なし
パスワード
   Jakzさん、Jカーターさん、色々ありがとうございます。実はちょっとあきらめかけていたので、今日覗いてみてびっくりしてしまいました。本当にありがとうございます。
お二人のアイデアをぜひとも試させていただこうと思います。実は今のところ、行き詰った急場の策として、あらかじめ3次元の配列(実は!!・・・運用時にはリスト表示の項目にあわせて、5〜6次元になる予定です)を10こ先に宣言してしまい、別にカウンタ
を使ってどこまでデータを格納しているのかチェックしています。Jakaさんのおっしゃるように、次元が増えるとメモリを食い、遅くなりそうで心配です。

添字を逆にするというテクニックは気がつきませんでした。また、最初にAdditemをつかってみたのですが、これだけだと列ごとにデータをセットすることが出来ず、配列にしようと思いました。まだ何かいい方法があったらぜひ教えてください。よろしくお願いいたします。ありがとうございました。

【7438】Re:2次元(多次元)配列の宣言について
回答  Jaka  - 03/9/5(金) 9:15 -

引用なし
パスワード
   おはようございます。
昨日本を見ていたら、ListBox1.Columnを使えばTransposeする必要がないと気付きました。
結果これだけで済んでしまいました。

Dim A() As String

Private Sub CommandButton1_Click()
  Dim X As Integer
  X = ListBox1.ListCount
  ReDim Preserve A(0 To 1, 0 To X)
  A(0, X) = TextBox1.Value
  A(1, X) = TextBox2.Value
  ListBox1.Column = A
  DoEvents
End Sub

また、最初にリストボックスの数を想定してリストボックスを区切っておく方法もある事に気付きました。
これだと最初に想定した行数以上は書きこめませんけど...。
想定した行数をオーバーした場合は、作りなおしになります。
新たに大きな配列を作って書きこんであるデータを移してから、と前に書きこんだような感じに
したりするとか、ちょっと面倒くさそうですが..。

Private Sub CommandButton5_Click()
  Dim TB() As String
  Static CNT As Long
  Const LCC = 10     '取合えず最初に0〜10まで、計11コ作っておく。
  If ListBox1.ListCount = 0 Then
    ReDim TB(0 To LCC, 0 To 1)
    ListBox1.List = TB
    Erase TB
    CNT = 0
  Else
    CNT = CNT + 1
  End If
  If CNT <= LCC Then
    ListBox1.List(CNT, 0) = TextBox1.Value
    ListBox1.List(CNT, 1) = TextBox2.Value
  End If
End Sub

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