ganbaruzo
@ganbaruzo

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

二次元配列→一次元配列+一次元配列というように、ReDim Preserveでしたい

二次元配列→一次元配列+一次元配列というように、ReDim Preserveでしたいのですが、上手くいきません。大変お手数が、どなたか、教えて頂けないでしょうか?初心者なので、多分やっていることが意味不明かもしれませんが、ご了承ください。コードもおかしい所が多々あります。すみません。Excel2010のバージョンです。

例)

Qiita質問2.jpg

該当するソースコード

Option Base 1
Sub 二次元配列→一次元配列6() 'sheet1(3)
   Dim myname() As Variant
   Dim i As Long
   Dim two_arr As Variant, one_arr1, one_arr2 As Variant
   
   two_arr = Range("a1").CurrentRegion
   
   one_arr1 = Application.Index(two_arr, 1)
'   Stop
   ReDim myname(8)
   For i = 1 To 8
      myname(i) = one_arr1
'      Stop
   Next i
'   For r = 1 To 8
      one_arr2 = Application.Index(two_arr, 2)
'      Stop
   ReDim myname(8)
      For i = 1 To 8
      myname(i) = one_arr2
'      Stop
   Next i
   ReDim Preserve myname(8 + 8)

   For i = 1 To 16
      myname(i) = Cells(i, 1).Value
   Next i
   
   For i = LBound(myname) To UBound(myname)
   
   Cells(i + 4, 1) = myname(i)
   Next i
End Sub

例)

def greet
  puts Hello World
end

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

0

3Answer


//ここで mynameに1と9を入れていると思うのですが。
 For i = 1 To 16
      myname(i) = Cells(i, 1).Value
   Next i

VBA,Excel 詳しくないですが書いてみたのですが、どうですかね?
これが動くのであれば、原因が単純なのですが。


//ここはそのまま
Option Base 1
Sub 二次元配列→一次元配列6() 'sheet1(3)
   Dim myname() As Variant
   Dim i As Long
   Dim two_arr As Variant, one_arr1, one_arr2 As Variant
   
//入力 

For i = 1 To 16
      if i < 9 
      myname(i) = Cells(i, 1).Value
      Else
      myname(i) = Cells((i % 9 +1), 2).Value
      End If
   Next i
   
//出力
   For i = LBound(myname) To UBound(myname)
   
   Cells(i + 4, 1) = myname(i)

  Next i
End Sub

0Like

Comments

  1. @ganbaruzo

    Questioner

    ありがとうございます。if i < 9 、if<9 thenが抜けているのと、myname(i) = Cells((i % 9 +1), 2).Valueがエラーが出ます。動きません。自分は、ReDim Preserveを使って、一次元配列+一次元配列としたいので、せっかく、解答、頂いたのですが、自分の思ってたと違います。今後の参考とさせて頂きます。
  2. 見当違いをすいません、
    いちよう、わたしが予想する原因が
    ここでのみ値が設定されていること
    Cells(行インデックス, 列インデックス)で列1の行1~16を取得のため
    1と9のみ取得していると思っていますが。。。

    ```
    For i = 1 To 16
    myname(i) = Cells(i, 1).Value
    Next i

    ```

    デバックとして、値の設定と出力をワンセットで毎回入れることを変化をだどるためにおすすめします。

    編集追加

    自己満足なので気にしないでください。
    余りは Modです。
    Cells((i Mod 9 +1), 2).Value

    意図としては、上のですべて出るのであれば
    myname(i) = Cells(i, 1).Valueがあったのでこれを書き換えれば終わりではと、
    タイトル無視してますねはい。。

    今回のReDim Preserveについては
    こちらの
    http://officetanaka.net/excel/vba/statement/ReDim.htm

    一個目のコード(失敗例)
    ReDimを実行したときに「東京」と「横浜」がクリアされます
    これに陥っているのでは?

  3. @ganbaruzo

    Questioner

    ありがとうございます。
  4. たびたびすいません、
    出力位置の列を 2にして
    Cells(i + 4, 1) = myname(i)

    A列の行1~16まで値を入れていただき実行していただくと行1~16までの値が
    出力されませんかね。?
  5. @ganbaruzo

    Questioner

    変わりません。ありがとうございます。
  6. Option Base 1
    Sub 二次元配列→一次元配列6() 'sheet1(3)
    Dim myname() As Variant
    Dim i As Long
    Dim two_arr As Variant, one_arr1, one_arr2 As Variant
    ' 入力範囲
    two_arr = Range("a1").CurrentRegion
    ' 行1の 列のA~Hまで
    one_arr1 = Application.Index(two_arr, 1)
    'mynameの1~8の要素に行1の列A~Hの値を入れる
    ReDim myname(8)
    For i = 1 To 8
    myname(i) = one_arr1(i)
    Next i
    ' 行2の 列のA~Hまで
    one_arr2 = Application.Index(two_arr, 2)

    'mynameの9~16の要素に行2の列A~Hの値を入れる
    ReDim Preserve myname(8 + 8)
    For i = 9 To 16
    myname(i) = one_arr2(i - 8)
    Next i
    '出力
    For i = LBound(myname) To UBound(myname)
    Cells(i + 4, 1) = myname(i)
    Next i
    End Sub


    こちらで、実行確認もできましたがどうでしょう?これも動かないなら、
    私では、わからないですね。
  7. @ganbaruzo

    Questioner

    コメントをすぐに頂いているのに、なかなか直ぐに返せなくて、すみません。言い訳に聞こえるかもしれませんが、資格試験の勉強をしながら、VBAのインプット、アウトプット、する日を決めて交互に勉強しています。同時、並行の勉強で時間が取れず、もがいていました。コメントも分かりやすく、まさに、自分が思った通りのコードです。For i = 9 To 16 myname(i) = one_arr2(i - 8) for i = 9 to 16も自分もコード、かけたのですが、myname(i) = one_arr2(i - 8)、i-8が全然思い浮かばなかったですね。初心者と仰っていましたが、本当に初心者とは思えない、自分は8か月、VBA勉強しているのに、逆に自分のスキルの低さに、頭が上がりません。いろいろ、試行錯誤されて、直ぐに、理解できる若い方は、羨ましいです。いろいろ、親身になって、対応して下さり、本当にありがとうございました。大変、助かりました。やはり、配列は難しいです。長文で大変、失礼いたしました。

配列の要素数が未確定のときに、ReDimを使いたい気持ちは解るのですが、
配列ではなくCollectionも検討してみても良いかもですね。
まぁ、事前に要素数は算出できそうではありますが。

もしくは、例には挙げていませんが、
VBA以外の他言語も含め、よく使う処理として、
split()などで文字列を分離させると、Variant型の配列に自動で格納できます。
(文字列処理の際に知っておくと便利です)

arr = Range("A1").CurrentRegion

を実行した直後に、ウォッチ式などで、

格納先の変数arrが、
どのような型で、どのような配列になっているのか
調べながらプログラムを書くことをお勧めします。

そもそも、WorkSheet/Rangeオブジェクト自体、
事実上無制限の2次元配列ですし、
1次元と2次元を区別して必要な理由が不明なので
あえて要件は達成させていませんが、処理例を挙げておきます。

Sub てきとう()
    Dim myname(1 To 2, 1 To 8) As Variant
    Dim i As Long
    Dim arr As Variant
   
    arr = Range("A1").CurrentRegion
   
    For i = 1 To 8
        myname(1, i) = arr(1, i)
    Next i

    For i = 1 To 8
        myname(2, i) = arr(2, i)
    Next i

    For i = 1 To 16
        If i <= 8 Then
            Range("D5").Cells(i, 1).Value = myname(1, i)
        Else
            Range("D5").Cells(i, 1).Value = myname(2, i - 8)
        End If
   Next i
End Sub
0Like

Comments

  1. @ganbaruzo

    Questioner

    こういうやり方もあるんですね。ありがとうございますー。コードの色はどうやって、変りますか?分からなくて、自分のは白色でー。

コードの挿入開始の先頭行で、言語の指定ができますよ。

Visual Basicであれは、

```vb:ファイル名

から始めれば...

0Like

Comments

  1. @ganbaruzo

    Questioner

    そうなんですね。Qiita初心者で、分からなくて、すみません。親切にありがとうございます。

Your answer might help someone💌