• 締切済み

配列のコピー

BVA初心者です。 基礎の基礎なのですが、質問させていただけないでしょうか。 excel VBAで、いま画面に 12345678910 12345678910 12345678910 ・・・・・・ と、あります。 これと、同じ配列を、右端にも作りたいのですが、 ”A(i, 1) = A(i, JMAX + 1)” のような記述方法で、全体をコピーすることはできますか?(copyメソッドは使わないで、できるはずなのですが・・・。) コピーができずに困ってます、よろしくお願いします。 Const IMAX As Long = 10 Const JMAX As Long = 10 Sub A() Cells.Clear Dim A(IMAX + 1, JMAX + 1) As Long Dim B(IMAX + 1, JMAX + 1) As Long For i = 1 To IMAX + 1 For j = 1 To JMAX Cells(i, j) = j A(i, 1) = A(i, JMAX + 1) '左端の配列を一番右にコピーする A(i, JMAX + 2) = A(i, 2) '左から2番目の配列を右から2番目にコピーする Next Next End Sub

みんなの回答

noname#22222
noname#22222
回答No.2

s_husky です。 cells.clear が、原因です。 クリアすれば当然に0! Option Explicit Option Base 1 Private Sub CommandButton1_Click()   Const conRMAX = 5   Const conCMAX = 2   Const conOFFSET = 10   Dim R             As Integer   Dim C             As Integer   Dim X             As Integer   Dim lngLeft(conRMAX, conCMAX) As Long   Dim lngRight(conRMAX, conCMAX) As Long     For R = 1 To conRMAX     For C = 1 To conCMAX       X = conCMAX - C + 1       lngLeft(R, C) = Cells(R, C)       lngRight(R, X) = lngLeft(R, C)       Cells(R, conOFFSET - X) = lngLeft(R, C)       Cells(R, C) = "" ' ここでクリアすべし!     Next C   Next R End Sub

nanakokko
質問者

お礼

なるほど!! できました! ありがとうございます、まだまだ勉強が足りないのだな、と実感させられました。 重ねがさね、お忙しいところありがとうございます。 Option Explicit Option Base 1 Private Sub CommandButton1_Click() Const conRMAX = 5 Const conCMAX = 2 Const conOFFSET = 10 Dim R As Integer Dim C As Integer Dim X As Integer Dim lngLeft(conRMAX, conCMAX) As Long Dim lngRight(conRMAX, conCMAX) As Long For R = 1 To conRMAX For C = 1 To conCMAX X = conCMAX - C + 1 lngLeft(R, C) = Cells(R, C) lngRight(R, X) = lngLeft(R, C) Cells(R, conOFFSET - X) = lngLeft(R, C) Cells(R, C) = 9 Next C Next R End Sub

noname#22222
noname#22222
回答No.1

多分、練習でしょうから・・・。 1  2        1  2 1  2        1  2 1  2        1  2 1  2        1  2 1  2        1  2 こういう風にやりたいのならば! Option Explicit Option Base 1 Private Sub CommandButton1_Click()   Const conRMAX = 5   Const conCMAX = 2   Const conOFFSET = 10   Dim R             As Integer   Dim C             As Integer   Dim X             As Integer   Dim lngLeft(conRMAX, conCMAX) As Long   Dim lngRight(conRMAX, conCMAX) As Long      For R = 1 To conRMAX     For C = 1 To conCMAX       X = conCMAX - C + 1       lngLeft(R, C) = Cells(R, C)       lngRight(R, X) = lngLeft(R, C)       Cells(R, conOFFSET - X) = lngLeft(R, C)     Next C   Next R End Sub

nanakokko
質問者

補足

ありがとうございます。 ほんとに速い返事が来たので、嬉しかったです! でも・・・ このコードでやってみても、希望通りの結果にはなりませんでした、、、どうして? 結果は、 0 0 0 0 0 0 ・・・・・・・ のようになってしまいます。 これでは、どこをコピーしたのか、わからないのですね。 大変お手数おかけしますが、なにが足りないのか、わかったら教えていただけませんでしょうか? (回答の記述はここでは、lingLeft=B, lingRight=Aと置き換えてあります。) Option Explicit Option Base 1 Private Sub CommandButton1_Click() Cells.Clear Const conRMAX = 5 Const conCMAX = 2 Const conOFFSET = 10 Dim R As Integer Dim C As Integer Dim X As Integer Dim B(conRMAX, conCMAX) As Long Dim A(conRMAX, conCMAX) As Long For R = 1 To conRMAX For C = 1 To conCMAX X = conCMAX - C + 1 B(R, C) = Cells(R, C) A(R, X) = B(R, C) Cells(R, conOFFSET - X) = B(R, C) Next C Next R End Sub

関連するQ&A

  • 塗る部分と塗らない部分を条件によってわけたいのですが・・・

    今回困っているのは下のマクロで (1)紺なら足跡を残し、青なら進んでいるセルだけ青にして前回の青の足跡は残さないで (2)セルが紺の足跡でいっぱいになるまで、これを続けます。 この条件をここに追加しようと思ったのですが、なかなかうまく行きません。ヒントだけでも、何か名案がありましたらご回答お願いします。 Const IMAX As Long = 30 '最大 i 座標 Const JMAX As Long = 20 '最大 j 座標 Const NMAX As Long = 50 '最大ステップ数 Const motigomi As Long = 5 'ゴミ「○歩につき●個捨てる」数 Dim ip(MMAX) As Long '人の i 座標 Dim jp(MMAX) As Long '人の j 座標 Dim occ(IMAX, JMAX) As Long Dim pre(IMAX, JMAX) As Integer Dim post(IMAX, JMAX) As Integer Sub ashiato() Randomize Cells.Clear For n = 1 To NMAX 'ステップを進める For m = 1 To 1   iprev = ip(m) '元いた位置 jprev = jp(m) '移動先 (i, j) を決める i = i - 1 '周期境界条件 If i > IMAX Then i = i - IMAX If i < 1 Then i = i + IMAX If j > JMAX Then j = j - JMAX If j < 1 Then j = j + JMAX '実際に移動 ip(m) = i jp(m) = j '色付けを更新 pre(i, j) = Int(motigomi * Rnd()) If pre(i, j) = 1 Then Cells(i, j).Interior.color = RGB(10, 50, 100) Else Cells(iprev, jprev).Clear Cells(i, j).Interior.color = RGB(40, 50, 400) End If Next Next End Sub

  • ExcelのVBAの配列に関する質問です。

    ExcelのVBAの配列に関する質問です。 sheet1のデータをsheet2に表示するVBAを作成しています。。 sheet1のデータは7行目からスタートし、sheet2のデータは26行目からスタートしています。。 sheet1とsheet2の列は同じ並びではないため、それぞれのシートの列番号をCellsを用いて指定しています。 Sub test1() Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 Worksheets("sheet2").Cells(j, 1) = Worksheets("sheet1").Cells(i, 2) Worksheets("sheet2").Cells(j, 8) = Worksheets("sheet1").Cells(i, 28) Worksheets("sheet2").Cells(j, 9) = Worksheets("sheet1").Cells(i, 31) Worksheets("sheet2").Cells(j, 10) = Worksheets("sheet1").Cells(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub 上記のtest1は正常に動くのですが、データ量が多いため、処理に時間がかかってしまいます。 高速化できないかと、以下のように変更しました。 Sub test2() Dim dataRange1 As Variant Dim dataRange2 As Variant dataRange1 = Worksheets("sheet1").Range("A1:GI10006") dataRange2 = Worksheets("sheet2").Range("A1:DZ10018") Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 dataRange2(j, 1) = dataRange1(i, 2) dataRange2(j, 8) = dataRange1(i, 28) dataRange2(j, 9) = dataRange1(i, 31) dataRange2(j, 10) = dataRange1(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub test2は、エラーメッセージ等は表示されませんが、sheet2にデータが表示されません。 ちなみに、以下のようにsheet1のみ配列化した場合は、正常に表示されました。 Worksheets("sheet2").Cells(j, 1) = dataRange1(i, 2) Worksheets("sheet2").Cells(j, 8) = dataRange1(i, 28) Worksheets("sheet2").Cells(j, 9) = dataRange1(i, 31) Worksheets("sheet2").Cells(j, 10) = dataRange1(i, 32) test2は、どこが間違っているのでしょうか? ご教示ください。 よろしくお願いいたします。

  • EXCELの配列で

    メールの本文を1行づつよみとってEXCELへ書き出そうと思っています。 Sub getMail1() Dim myOl As New Outlook.Application Dim dFolder As MAPIFolder Dim myItem As MailItem Dim delItem As MailItem Dim myRecipient As Recipient Dim i As Long, j As Long Const mAddress = 0, mTel = 1, mName = 2, mAge = 3 Set dFolder = myOl.GetNamespace _ ("MAPI").Folders("個人用フォルダ").Folders("単発") i = 1 On Error Resume Next For Each myItem In dFolder.Items i = i + 1 Set delItem = myItem.Reply For Each myRecipient In delItem.Recipients If InStr(1, myRecipient.Address, "@", vbBinaryCompare) _ <> 0 Then Exit For End If Next delItem.Delete With ActiveSheet myBody = Split(myItem.Body, vbCrLf) .Cells(i, 1).Value = myRecipient.Address .Cells(i, 2) = myItem.SenderName .Cells(i, 3) = myItem.Subject .Cells(i, 4) = myItem.ReceivedTime For j = 0 To UBound(myBody) i = i + 1 On Error Resume Next .Cells(i, 1) = myBody(j) .Cells(i, 1).MergeCells = True Next End With i = i + 1 Next Set myOl = Nothing End Sub このようなコードを書いて書き出すことは出来たのですが配列が縦になってしまいます。 横に配列したいのですが教えてください。 伊藤太郎 東京都 03-3123-4567を 伊藤太郎 東京都 03-3123-4567 としたいです。 よろしくお願いします。

  • Excel VBA ユーザフォームの検索について

    添付の画像のようなユーザフォームを作っています。 TextBox1に検索ワードを入力して、CommandButton1をクリックすると、下のComboBox1に一覧が出るようにしたいと思い、ほかのサイトから下記のコードを見つけて、作ってみました。参照先のsheet2を表示しているときは大丈夫なのですが、別のシートを選んでいるとエラーになります。 sheetは3つあり、それぞれ違うリストが入力されています。今回はsheet2のリストを参照したいのですが、最初はsheet1が表示されている状態で実行したいです。 エラーの内容は 実行時エラー9 インデックスが有効範囲にありません。 コチラがコードです。 Private Sub UserForm_Initialize() Dim i As Long, imax As Long Dim tbl() As Variant imax = ThisWorkbook.Worksheets("sheet2").Cells(Rows.Count, "A").End(xlUp).Row ReDim tbl(imax) For i = 1 To imax tbl(i) = Range("A" & i).Value Next i With ComboBox1 .List() = tbl() End With End Sub Private Sub CommandButton1_Click() Dim i As Long, imax As Long Dim tbl() As Variant Dim cnt As Long, j As Long j = -1 With ThisWorkbook.Worksheets("sheet2") imax = .Cells(Rows.Count, "A").End(xlUp).Row cnt = Application.CountIf(Range("A1:A" & imax), "*" & TextBox1.Text & "*") ReDim tbl(cnt) For i = 1 To imax If InStr(.Range("A" & i), TextBox1.Text) > 0 Then j = j + 1 tbl(j) = Range("A" & i).Value ←この部分がエラーになる End If Next i End With With ComboBox1 .List() = tbl() End With End Sub どこを直せば良いか、教えてください。 よろしくお願いします。

  • 配列のフリーズを解消してください。

    Sub データ原本() Dim wsAll As Worksheet Set wsAll = Worksheets("All(5)") Dim lRow As Long, lCol As Long Dim i As Long, j As Long, cnt As Long With Worksheets("データ原本") '日付S行を日付に変更(「.」を「/」に置換) lRow = .Cells(Rows.Count, 1).End(xlUp).Row Dim MyArray As Variant MyArray = Range(.Cells(10, 1), .Cells(lRow, 1)) For i = 1 To lRow - 9 MyArray(i, 1) = Replace(MyArray(i, 1), ".", "/") Next Range(.Cells(10, 1), .Cells(lRow, 1)) = MyArray Erase MyArray '配列の初期化 '「天気」両サイドの &「内・外」両サイドの空白スペースを削除 lRow = .Cells(Rows.Count, 1).End(xlUp).Row MyArray = Range(.Cells(10, TNK), .Cells(lRow, TNK)) For i = 1 To lRow - 9 MyArray(i, 1) = Trim(MyArray(i, 1)) Next Range(.Cells(10, TNK), .Cells(lRow, TNK)) = MyArray Erase MyArray '配列の初期化 '数値0のデータ行の行削除 lRow = .Cells(Rows.Count, 1).End(xlUp).Row lCol = .Cells(9, Columns.Count).End(xlToLeft).Column Dim arr_A As Variant, arr_B As Variant arr_A = Range(.Cells(9, 1), .Cells(lRow, lCol)).Value ReDim arr_B(1 To lRow - 8, 1 To lCol) cnt = 0 For i = 1 To lRow - 8 If arr_A(i, 18) <> 0 Then cnt = cnt + 1 For j = 1 To lCol arr_B(cnt, j) = arr_A(i, j) Next j End If Next i .Range("A9").Resize(lRow, lCol).Value = arr_B End With End Sub  上記のコードを2回実行すると2回目には、 MyArray(i, 1) = Replace(MyArray(i, 1), ".", "/")のところで「型が一致しません。」とフリーズします。かと言って 「 '数値0のデータ行の行削除」コードを一括削除して、実行ボタンを何度押してもフリーズすることはありません。どこに不具合が生じているのかわからないのですが、どなたか名回答を宜しくお願いします。

  • 配列を利用したコードにしてください

    下記コードですが 計算速度が遅いので配列を利用した コードに修正してください。お願いいたします。 Dim mx As long Dim Rp As Double Dim yy1 As Double Dim pai As Double Dim Ba AS long Dim i As long, j as long Dim K As Doubke Dim xx1 As Double, yy1 As Double Dim x0 As Double,y0 As Double Dim x1 As Double, y1 As Double mx = Sheets("nn").Range("B65536").End(xlUp).Row Rp1= Sheets("pp").Range("B65536").End(xlUp).Row yy1= Sheets("pp").Range("A25") With Sheets("zzz") pai=Atn(1) * 4 Ba=Sheets("sheet1").Range("A1")  For I = 1 To Ba K = -Sheets("sheet1").Range("B" & I + 3).Value * pai/180 xx1 = Sheets("sheet1").Range("C" & I + 3).Value   yy1 = Sheets("sheet1").Range("D" & I + 3).Value  For j = 1 To mx - 1 x0 = .Cells(2 + j, 2) y0 = .Cells(2 + j, 3) X1 = x0 * Cos(K) + y0 * Sin(K) Y1 = -x0 * Sin(K) + y0 * Cos(K) .Cells(2 + j, 2 * I + 2) = X1 + xx1 - Rp1 .Cells(2 + j, 2 * I + 3) = Y1 + yy1  Next j  Next I End with

  • 二次元配列のVBA

    二次元配列のVBAの書き方がよくわからないのですが、 私が作ったサンプルプログラムのSub 二次元()において 二次元配列で表すにはどうすればいいのでしょうか? Sub 二次元()では 配列を格納する変数はtmpしか使っていませんが もう一つ配列を格納する用の変数を作ればいいのでしょうか? 数字とアルファベットは別々に取り出したいです。 ----------------------------------------------------- Sub 一次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub Sub 二次元() Dim myStr As String Dim tmp As Variant Dim i As Long For i = 1 To 5 myStr = myStr & "," & i & "と" & Chr(64 + i) Next myStr = Mid(myStr, 2) tmp = Split(myStr, ",") For i = LBound(tmp) To UBound(tmp) Debug.Print tmp(i) Next i End Sub

  • VBAの動的配列について

    いつもお世話になっております。 エクセルVBAを学習中の者です。 動的配列についてお伺いします。 添付資料を見て頂きたいのですが、 シート名1~4に同一レイアウトの表があります。 これらの表をを2次元配列に格納し、その後、同一レイアウトのシートに一括転記したいと考えています。 転記の事を考えて、条件としては、 シート1から2行目以降のデータを配列『data』に格納、変数『dataCnt』が転記先の行番号と同じになるように考えています。 当初は、配列の定義を『Dim data(100,3) As Variant』と、多めに要素数を定義して、コードを記述していました。 正直、凄く気持ちが悪い感じでした・・・ 最近、動的配列を学習しまして、 シートごとにデータの行数を変数『lastRow』に格納して、配列を再定義して【データ数=要素数】とならないか? と思い、下記のようなコードを書いてみました。 が、『ReDim Preserve~』で実行エラーが発生してしまいます。 原因がなぜかわかりません! そもそも、動的配列はこのような使い方は出来ないのでしょうか? Sub テスト() Dim data() As Variant Dim x As Long Dim i As Long Dim ii As Long Dim lastRow As Long Dim dataCnt As Long dataCnt = 2 For x = 2 To 5 Worksheets(x).Activate lastRow = Cells(Rows.Count, 1).End(xlUp).Row If x = 2 Then ReDim data(2 To lastRow, 3) Else ReDim Preserve data(2 To dataCnt + lastRow - 1, 3) End If For i = 2 To lastRow For ii = 1 To 3 data(dataCnt, ii) = Cells(i, ii) Next ii dataCnt = dataCnt + 1 Next i Next x End Sub どなたかご指導をよろしくお願いいたします。

  • EXCEL VBAの配列でわかりません。

    こんなコードがあるのですが、最後の他のシート(作業中シート)に書き込もうとするとエラーになってしまいます。”Sheets("作業中").”を抜くと同じシートに結果は返ってくるのですが…。コードの内容は、ある範囲のある列から空白ではないセルを探し出してその行のデータを配列で汲み取り、他のシートに一括で洗い出すというものです。 Sub 作業中() Dim myRow As Long Dim Data As Variant Dim WC() As Variant Dim WCE() As Variant myRow = Range("H1").CurrentRegion.Rows.Count Data = Range("H1:M" & myRow).Value For i = 1 To myRow If Data(i, 5) <> "" Then a = a + 1 Else b = b + 1 End If Next ReDim WC(a) ReDim WCE(b) c = 0 d = 0 For i = 1 To myRow If Data(i, 5) <> "" Then WC(c) = Range("H" & i & ":K" & i).Value c = c + 1 Else WCE(d) = Range(Cells(i, 8), Cells(i, 11)).Value d = d + 1 End If Next For i = 0 To a Range(Cells(i + 1, 15), Cells(i + 1, 18)).Value = WC(i) Next For i = 0 To b Range(Cells(i + 1, 19), Cells(i + 1, 22)).Value = WCE(i) Next e = Range(Cells(1, 15), Cells(a, 18)).Value Sheets("作業中").Range(Cells(1, 1), Cells(a, 4)).Value = e End Sub ちなみに同じシートから↓のコードを実行するとうまくいきます。 なぜ~??わからな~い??おしえてくださーい!! Sub test() Dim a As Variant a = Range("H1:K4") Sheets("作業中").Range("N1:Q4") = a End Sub

  • VB バリアント型の配列の例について

    長々と失礼します。私の使用している教科書に 「バリアント型の2次元配列」と「バリアントに2次元配列を代入」というのを組み合わると「行列i要素とする行列」たとえば 2 5 9 4 1 8 7 3 6 1 5 9 8 0 1 6を的確に表現できます。 と書いており、下のように書かれているのですが上のような配列を表示しません。どこが間違っているのでしょうか?そもそも上のように表示できるのか理解に苦しんでおります Option Base 1 Private Sub Command1_Click() Dim a(2,2) As Variant Dim c(2,2) As Integer For i = 1 To 2 For j = 1 To 2 For p = 1 To 2 For q = 1 To 2 c(p,q) = p + q + i * j Next q Next p a(i,j) Next j Next i For i = 1 To 2 For p = 1 To 2 For j = 1 To 2 For q = 1 To 2 Print a(i,j)(p,q), Next q Next j Print Next p Next i End Sub

専門家に質問してみよう