• ベストアンサー

Excel2002 配列の取得

いつもお世話になっております。 Excelのデータを行単位で配列に書き換える処理を VBAで記述しています。 '****************************************************** '*** 行のループ処理(見出し行を含まず2行目から) For intCnt = 1 To intRow '*** 列のループ処理 For intCnt2 = 1 To 58  '*** セル範囲を配列変数に格納する varUPDT = wsWS.cells(intCnt, 1).Resize(intCnt, 58).Value  If intCnt2 = 1 Then  varDATA = "('" & varUPDT(intCnt, intCnt2) & "'" Else If varUPDT(intCnt, intCnt2) = Empty Then  varUPDT(intCnt, intCnt2) = 0 Else End If '*** テキスト型の列を指定  If intCnt2 = 2 Then  varDATA = varDATA & ",'" & varUPDT(intCnt, intCnt2) & "'" Else  varDATA = varDATA & "," & varUPDT(intCnt, intCnt2) End If End If Next intCnt2 varDATA = varDATA & ")" Next intCnt '****************************************************** 取得した結果を見ると、なぜか奇数行のみが 取得されています。 行の変数(IntCnt)は1ずつ増えていっているのに不思議です。 間違いをご指摘いただきたく存じます。 どうぞよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.2

無駄なコードを書くよりも for x  for y   Cells(x,y)  next next とした方がずっと単純ですね。

romiromi
質問者

お礼

ご回答ありがとうございます。 そうですね、確かに無駄ですね。 シンプルにしたほうが、別の方がメンテナンスをする場合も よいですものね。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.4

雑感。 (1)エクセルのセルは2次元配列的になっているのに、普通は配列に、改めて起す必要はないのではないか。自己プロでソートなどするときは必要と思いますが。VBAでの関数利用やメソッドが豊富で、それで凌げるはず。 (2)#2のご意見のごとく For i=1 to 10 For j=1 to 10 x=Cells(i,j) Next j Next i 式で済むはず。 (3)これは、私の趣味かもしれないが、変数名が丁寧で正式といえば言えるが、複雑で、見通しが悪い。int,varをつけて区別は意味があるのか。 (4)Redimなど使わなくてもVBAレベルでは済むように思う。 (5)コードの質問の場合、そのコード行(や行群)で何をしたいか、解説すべき。回答者や読者に全部解読させるのは、どうかと思う。 本質問は、CSVファイルの作成ですか? (6)テストデータがないと、この質問レベルではテストもできない ことがわかった。そこまで回答者に作らせるのもどうかと思う。 データによってエラーが出たり出なかったりは、しょっちゅう経験するから、再現にデータは大切。 (7)第1列目と第2列目以降をループに入れているが第2列目以降のループにして、A列は、Cells(i,”A")で参照しては。 わたしの言っていることの例。 Sub test01() Dim ws As Worksheet Set ws = Worksheets("aaa") For i = 1 To 5 '行変化 DATA = "('" & ws.Cells(i, "A") & "'" '(’をつけてDATAへセット For j = 2 To 5 '列変化 If j = 2 Then '第2列は文字列型で文字列型は DATA = DATA & ",'" & ws.Cells(i, j) & "'" Else 'C列以右は数値型で DATA = DATA & "," & IIf(ws.Cells(i, j) = "", 0, ws.Cells(i, j)) End If Next j DATA = DATA & ")" MsgBox DATA Next i End Sub テストデータで 東京 xxx 123 34 54 大阪 yyy 234 45 21 静岡 zzz 345 67 23 名古屋 uuu 5567 89 456 MsgBoxで ('東京','xxx',123,34,54) のようになりました。

romiromi
質問者

お礼

ご回答ありがとうございました。 明記する情報が不足しており、そのためにお時間、お手間を取っていただき申し訳ありません。 記述に関してのご指摘は、開発定義書に副わない内容も ありますが、今後の参考にさせていただきます。

全文を見る
すると、全ての回答が全文表示されます。
回答No.3

>Resize(intCnt, 58) ???

romiromi
質問者

お礼

コードを修正いたしました。 補足はいたしませんが、「変だ」という指摘をいただいて ありがとうございました。 ヘンでした。

全文を見る
すると、全ての回答が全文表示されます。
  • ipsum11
  • ベストアンサー率21% (55/251)
回答No.1

>取得した結果 と言うのは、varDATAのことですか? であるなら、デバッグしながら見ていくとこの変数には、ちゃんと奇数・偶数行の値が取得されています。ただ、配列ではないので毎回上書きされています。 ループが終了したときには最後の行がセットされています。 勘違いでしたらごめんなさい。

romiromi
質問者

お礼

ご回答ありがとうございました。 シンプルなコードに修正することで 今回は回避いたしました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VBA配列 印のついた列番号を格納して利用したい

    Excel VBAで下記処理を作成しました。配列を使えば処理が高速化できるのでは?と思い調べたのですが、配列を使ったことが無く、挫折しましたのでどなたかご教示いただけませんでしょうか。 <対象データ>(添付画像の黄色いセルが処理対象) ・処理対象の行は「区分」列に「0」が入っている ・処理対象の列は、1行目に「●」が入っている <作成した処理> ・ループ(1):データ開始行(画像では3行目)から順に見ていく  ・IF:「区分」列が「0」なら下記に進む(0以外なら次の行へ)   ・ループ(2):列を左から順に見ていく    ・IF:その列の1行目が「●」なら処理を行う For i = 3 To 10000 If Cells(i , 1) = 0 And Cells(i , 1) <> "" Then その行に対する処理の下準備のコード(記載省略) For j = 2 To 500 If Cells(1 , j) = "●" Then Cells(i , j)に対する処理(記載省略) End If Next j End If Next i <問題点> データ量が数千行×数百列と相応にあるため、処理実行に数秒かかります。今後、処理をより複雑にしたいため、高速化できないかと考えています。 <質問> 対象行について毎回、ループ(2)で各列の1行目を調べて●だったら処理する、としているのが非効率かも知れないと思いました。 1行目に●が入っている列番号を調べるのは1度で良いので、それを配列に格納して、ループ(2)の部分で使うことはできますでしょうか? ご存じの方、ご教示いただけますと幸いです。よろしくお願いいたします。

  • シートAとシートBの得意先コードが一致したら、該当行をシートCにコピー

    シートAとシートBの得意先コードが一致したら、該当行をシートCにコピーするVBAを組みたいのですが、上手く行きません。加えてシートAの該当行は削除しておきたいです。 XPでExcel2003を使用しています。 Const strMasSheet = "A" Const strMasSheet2 = "B" Const strSrhSheet = "C" Dim strSrhCode As Long 'シートAの得意先コード Dim strSrhCode2 As Long 'シートBの得意先コード Dim intRow As Long Dim intRow2 As Long Dim intCnt As Long Dim maxgyo As Long 'シートAの最終行 Dim maxgyo2 As Long 'シートBの最終行 Sub データを分ける() maxgyo = Sheets(strMasSheet).Cells(Rows.Count, 1).End(xlUp).Row 'シートAの最終行を取得 For intRow = 2 To maxgyo '2行から始めて最終行まで(1upで) strSrhCode = Sheets(strMasSheet).Cells(intRow, 2) '検索値 B列= 得意先CDを取得 maxgyo2 = Sheets(strMasSheet2).Cells(Rows.Count, 1).End(xlUp).Row 'シートBの最終行を取得 For intRow2 = 2 To maxgyo '2行から始めて最終行まで(1upで) strSrhCode2 = Sheets(strMasSheet).Cells(intRow, 8) '検索値 H列 = 得意先CDを取得 intCnt = 2 '2行から If strSrhCode = strSrhCode2 Then 'もし検索値と検索対象シートの得意先CDが一致したら intCnt = intCnt + 1 With Sheets(strSrhSheet) .Cells(intCnt, 1) = Cells(intRow, 1) .Cells(intCnt, 2) = Cells(intRow, 2) .Cells(intCnt, 3) = Cells(intRow, 3) .Cells(intCnt, 4) = Cells(intRow, 4) .Cells(intCnt, 5) = Cells(intRow, 5) .Cells(intCnt, 6) = Cells(intRow, 6) .Cells(intCnt, 7) = Cells(intRow, 7) .Cells(intCnt, 8) = Cells(intRow, 8) .Cells(intCnt, 9) = Cells(intRow, 9) .Cells(intCnt, 10) = Cells(intRow, 10) .Cells(intCnt, 11) = Cells(intRow, 11) End With End If Next intRow2 Next intRow MsgBox "処理終了" End Sub 言葉足らずの所があればごめんなさい。 追記いたしますので、教えて下さい。 よろしくお願い致します。

  • 【Excelマクロ】もっと頭の良い書き方って無いかな?

    5行空白列があったらそこで処理を終わりたいんですが、もっといい書き方はないでしょうか? 下記が私の考えた頭の悪いやり方です。 Sub macro() Dim i As Integer For i = 1 To 1000 If Cells(i, 1) = "" Then  If Cells(i + 1, 1) = "" Then   If Cells(i + 2, 1) = "" Then    If Cells(i + 3, 1) = "" Then     If Cells(i + 4, 1) = "" Then      If Cells(i + 5, 1) = "" Then       MsgBox (i - 1 & "行目で終わりです")       Exit For      End If     End If    End If   End If  End If End If Next End Sub

  • ●Excel VBA 配列●教えて下さい

    a~tの文字が順々に文字を追っていくプログラムにしたいと思い 配列を使用したのですが…プログラムが稼動しません、 下記のプログラムでは何が足りないのでしょうか わかる方いたら教えて下さい; 配列の使い方についてアドバイスがあれば そちらも教えていただきたいです…。 '――ここから―― Dim time1 As Integer, time2 As Integer, n As String Dim X As Integer, Y As Integer Dim yoko As String, tate As String Dim suuji (19) As String Sub 描画() Cells(X, Y).Value = suuji End Sub Sub 削除() Cells(X, Y).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() If yoko = "右" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 30 Then yoko = "左" ElseIf Y = 1 Then yoko = "右" End If If tate = "上" Then X = X + 1 Else X = X - 1 End If If X = 20 Then tate = "下" ElseIf X = 1 Then tate = "上" End If End Sub Sub main() suuji (0) = a suuji (1) = b suuji (2) = c suuji (3) = d suuji (4) = e suuji (5) = f suuji (6) = g suuji (7) = h suuji (8) = i suuji (9) = j suuji (10) = k suuji (11) = l suuji (12) = m suuji (13) = n suuji (14) = o suuji (15) = p suuji (16) = q suuji (17) = r suuji (18) = s suuji (19) = t For n = 0 To 19 Cells(X,Y).Value = suuji (n) Next X = 1 Y = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub '――ここまでです―― 何度も同じような質問をさせてもらってすみません;

  • VBA、Excel、文字列の置換について

    エクセルのVBAを勉強しているものなのですが 行き詰ってしまったので有識者の方、アドバイスをお願いします 目的:セルに入力されているカンマで区切られた文字列(例、1,2,5,6,7,8,10,11・・・)で連番の場合間の数字を"-"で省略(例、1,2,5-8,10,11・・・)する関数の作成 以下、プログラム (1)カンマで区切られた文字列をスプリットし、配列化 For Each cl In moji myData = Split(cl, ",") Next (2)3つ以上の連番の場合、"-"で文字列の短縮化 For l = 1 To UBound(myData) If myData(l) = myData(l + 1) - 1 Then If myData(l) = myData(l - 1) + 1 Then myData(l) = "-" ElseIf myData(l) = "-" Then myData(l) = "" Else myData(l) = myData(l) & "," End If Else myData(l) = myData(l) & "," End If Next l (3)配列をカンマで区切られた文字列として出力 For m = 0 To UBound(myData) bunkai = bunkai & myData(m) Next m

  • 動的配列が存在(要素が有る)か否かを判定できますか?

    VBAで、「For ループが初期化されていません」エラーが発生します。 動的配列が要素0の時に発生するようです。 動的配列の要素が生成された場合だけ、Forループしたいのですが、 どうやって判定すればよいのでしょうか? ------------------------------- Dim 配列() As Integer Dim i As Integer i = 0 If (i < 0) Then ' 本当は真になったり偽になったり ReDim 配列(0 To i) 配列(i) = a + b i = i + 1 End If '' if ★★★ then '' 配列が有るか確認 For Each c In 配列 MsgBox c Next '' end if -------------------------------

  • エクセルVBAの配列について

    エクセルVBAの配列について VBAをはじめたばかりの初心者です。 現在、下記のようにデータを配列の中に入れ、 別シートに書き出そうとしております。 (配列へ読み込むところのみ) Dim 配列(1 To 件数, 1 To 9) As Variant For j =1 To 件数 For i = 2 To L If Cells(i, 2).Value = Tx_month Then For k = 3 To 11 配列(j, k - 2) = Cells(i, k).Value Next k End If Next j,i 現状では、データの最終行のみを「件数」分書き出してしまいます。 jとiのForが重なっているからだと思うのですが、どう書き直したら良いか分かりません。 質問をさせていただくのも初めてなので、分かりづらく恐縮ですが お力添え頂けますと幸いです。 どうぞ宜しくお願い致します。

  • Excel(VBAを使用して書式の大量コピー)

    お世話になっております 以下の内容を行っているのですが、処理が遅くもっと効率の 良い方法がないかご教授いただければと思います win2000 Excel200 ExcelのA列のデータが10000件ほど入っております ただし、IF文などの書式が入ってる行と入ってない行があり 書式の入っている行だけ新しい書式を設定したいと思ってます For intCnt = 1 to 10000 もしも書式が入っていたら新しい書式にする IF Left(Trim(Range("A" & intCnt).FormulaR1C1), 1) = "=" Then      range(A1) = "新しい書式" End if next このような感じで行ってますが、処理に時間がかかります なんとか、速度UPを考えてますが、何か良い案はございますでしょうか? 宜しくお願い致します

  • VBS 複数ファイル複数行を配列格納

    ある配下のCSVファイル2個(固定)を読み込み、 コンピュータ名の列が同じ行を比較するというツールを作っています。 考えた結果以下まではできましたが、どうしても指定行を配列に埋め込み処理ができません。 比較方法はわかります。 ですが以下のプログラムでは、CSVの行は複数行あるので最終行しか格納されません。 どのようにしたら、2つのCSVファイルそしてすべての行を配列に入れ込むことができるのでしょうか。 For Each FileName In src.Files FileEx = fso.GetExtensionName(FileName) If LCase(FileEx) = "csv" Then Set CsvFile = fso.OpenTextFile(FileName) Do Until CsvFile.AtEndOfStream tmpLine = CsvFile.ReadLine If roopCnt = 0 Then '1個目のCSV ArrayA = Split(tmpLine,",") Else '2個目のCSV ArrayB = Split(tmpLine,",") End rowCnt = rowCnt +1 Loop roopCnt = 1 End If Next

  • Forループの制御について

    VB 2005,Framework2.0を使用しています。 For文を使ったループについてお尋ねしたいことがあります。 For i As Integer = 0 To 10     ’処理 Next i とあったとします。 そうするとループ変数iが0から10になるまで連続してループを行うのですが、これをある条件の時に現在のループ変数から一つ飛ばして次のループからまた処理を行いたい場合どのようにすれば良いのでしょうか? 例えば0~10回中に、現在5回目で特定の条件が一致したときその次の6回目のループは飛ばして7回目のループから再開したいです。 ちなみにこの様に書いても0から10回必ずループされてしまいました。 Dim TEST(10) As Integer TEST(5) = 1 For i As Integer = 0 To 10 If TEST(i) = 1 Then i = i + 1 End If Next i

専門家に質問してみよう