• ベストアンサー

エクセル(VBA)の空白配列の削除について

エクセルのVBAで配列を使おうと考えています。 データ配列 = Split(データ源, Chr(13)) として、1次元配列に取り込んだところ、chr(10)だけが入力されたデータ配列(?)が出来てしまいました。このデータ配列を詰めたいのですが、何かいい方法が無いでしょうか?教えてください。 元の配列 データ配列(0)  "てすと1" データ配列(1)  chr(10) データ配列(2)  "テスト2" とすれば、 詰めたあと、 データ配列(0)  "てすと1" データ配列(1)  "テスト2" となるようにしたいのです。(配列の最大数が減る必要が必ずしもありません。) for each で回せばいいのでしょうか? Dim 仮 AS Variant for Each 仮 In データ配列    処理をここに書く Next では、上手く行きませんでした。 どなたか?詳しい方がいらっしゃいましたら教えてください。宜しくお願い致します。

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

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.5

すみません。コメントが一部不適切でした。   ' Filter 関数で Chr(10)を含むデータを取り除く は   ' Filter 関数で ・を含むデータを取り除く の誤りです。もちろん Chr(10) を含むデータを取り除くことも可能です。 これだけだと、しょうもない回答なので、横レスになってしまい、恐縮ですが、、 > 変数をカウント(例:i=i+1)に使わないと分からないのでしょうか? その場合は、通常 For Each ではなくて、最初から For ~ Next を使います。 > 配列から条件に一致したするものを取得した場合にどの配列番号から取得 > したのか? Application.Match で調べられます。 > 2バイト文字を使うと誤動作...半分、見栄えや、入力のしやすさだけで、 > 使わないのかと思っていましたが? 例えば、 Dim strText と宣言してあると、コーディング時に strtext と入力しても自動的に strText に変換されます。コーディング時に入力のパンチミスを発見できるわけですが、 2バイト文字の場合、この機能は使えません。合理的な理由としてはこれ。 可読性については人それぞれなので、自分で使う分には2バイトを使っても構わ ないかもしれませんが、私はコメントとコードの境界がなくなって「読み難い」 し、嫌う人は多いです。 2バイト文字の変数やプロシージャ名が原因で誤動作するかどうかについて、 誤動作する可能性があるとの話は聞いたことがあります。しかし、実際に自分で 体験したことはありません。

vba_minarai
質問者

お礼

重ね重ねの質問にも、丁寧に丁寧を重ねたご回答有難う御座います。 >For Each ではなくて、最初から For ~ Next は、For ~ Nextよりも、For Each の方が内部処理が早いと聞いたもので、使えないかと思いましたが、やはり無理なんですね?当然、その差が問題になるようなコードを書いているわけではないのですが、少し背伸びをしてみただけです。 Application.Match については、是非、活用させていただきたいと思います。何せ、よく分かっていないので、ヘルプなどを見ても、その書いている文章の価値が理解出来ないので、応用が利かないのが現実です。一寸したヒントでも頂けると凄く助かります。 2バイト文字については、今後良く考えて行きたいと思います。

その他の回答 (5)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

Wendy02です。 >変数をカウント(例:i=i+1)に使わないと分からないのでしょうか? 私は、個々の問題に対して回答をしましたが、For Each .. In ... が、For i = LBound(..) To Ubound(..) であろうが、あまり大差を感じているわけではありません。また、Filter関数を使うか使わないかは、ご自身の選択の範囲だと思います。 ただ、私個人は、一律にデータが規則どおりになっていればよいのですが、そうとは限らないので、実際には、Filter関数では、あまりうまく行かないような気がするので、使わないだろうと思っています。 最終的な目的が何か、ということが大事なので、 「Filterで、配列から条件に一致したするものを取得した場合にどの配列番号から取得したのか?を得る方法ってあるのでしょうか?」 というような実験的なものに対しては、直接的な回答は出来かねます。Filter関数を使わなくてはならない意味と、それによって配列の添え字を取得することは、私の経験にはないことです。その意義を見出せません。ご自身が、いろいろやってみることだと思います。 >2バイト文字を使うと誤動作ってするのですか? VBE内は、Unicodeですから、それが、あまり問題は少ないだろうとは思っています。特に、私の使用しているExcelは、日本語バージョンですので、トラブルは経験したことはありません。おそらく、これは、他の言語のVBAを想定したものかもしれません。事実、私の使用しているVBEユーティリティでは、日本語の部分は、文字化けしてしまいます。 それは別としても、これは、VBAの基礎のルールとして掲げられているものですから、回答する立場の私としては、コードを公にする以上は、一応、但し書きとしては書かざるを得ないのです。ご質問者個人が、プライベートでお使いになる分には、誰も関知するものではありません。

vba_minarai
質問者

お礼

なんだか?お怒りのようで、誠に申し訳ありません。 便乗質問したのが気に入らなかったようで、すみません。確かに、個々が、各々の条件でやろうとしていることを全て把握して答えるのは難解を極めると思います。もう少し、補足の使い方には重々に注意していきたいと思います。 これに、懲りずに今後とも宜しくお願い致します。 Wendy02さんのおかげで、随分VBAも自由に組めるように(当然、Wendy02さんの足元にも及ばないですが)なってきました。本当に、本当に有難う御座いました。

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.4

こんにちは。KenKen_SP です。 Chr(10)って vbLf のことですよね....どんなデータなのでしょうか? 今回の用途なら Filter 関数一行で済むと思いますが。 便宜上、Chr(10)を”・”にして、それを含む配列要素を取り除いています。 Sub Sample()   Dim A(5) As String   Dim Buf As Variant      ' テスト用配列データ   A(0) = "てすと1"   A(1) = "・"   A(2) = "テスト2"   A(3) = "TEST3" & "・"   A(4) = "・" & "TEST4"   A(5) = "・"      ' 処理前のデータを表示   MsgBox Join$(A, vbLf)        ' Filter 関数で Chr(10)を含むデータを取り除く   Buf = Filter(SourceArray:=A, _          Match:="・", _          Include:=False)      ' 取り除かれたか確認表示   MsgBox Join$(Buf, vbLf) End Sub

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 データ配列 = Split(データ源, Chr(13)) 果たして、そのようなことがありえるのか、データの入手方法が見えていないので、なんとなく、そういう配列の生成がヘンな気がしますが、それは置いておいて、すでに、データ配列という配列変数が出来上がったとすれば、後を以下のようにすれば、取れますね。 Dim データ配列 As Variant Dim 仮 As Variant '配列変数が、ここで出来上がったとして Dim データ配列2() As Variant Dim i As Long For Each 仮 In データ配列   If 仮 > Chr(30) Then   ReDim Preserve データ配列2(i)    データ配列2(i) = 仮    i = i + 1   End If Next (便宜的に、ここでは、2バイト文字の変数を使いました。本来は、誤動作の元になりますので、使ってはいけません。)

vba_minarai
質問者

補足

いつもいつも有難う御座います。 なるほど、別の動的配列を用意すればいいのですね?有難う御座います。あわせて、ご質問したいのですが、For Each で配列をループさせている時に、ある条件でIF文で引っかかった時に何番目の配列要素かどうかは、変数をカウント(例:i=i+1)に使わないと分からないのでしょうか? また、Filterで、配列から条件に一致したするものを取得した場合にどの配列番号から取得したのか?を得る方法ってあるのでしょうか? 重ね重ねよろしくお願いします。 2バイト文字を使うと誤動作ってするのですか?英語が苦手な私としては、可読性のために使っていますが??(プログラミングのどの本を読んでも、2バイトを使っている本って見たことありませんが・・・?半分、見栄えや、入力のしやすさだけで、使わないのかと思っていましたが?)

回答No.2

データ配列 = Split(データ源, Chr(13)) の前に データ源 = Replace(データ源, Chr(10), "") を入れてみたらどうでしょうか

vba_minarai
質問者

お礼

今回の質問の条件では、chibita_papaさんの仰る方法が合理的だと思いました。本当に有難う御座いました。点数が割り振れなくて誠に申し訳ありません。 今後とも宜しくお願い致します。

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.1

テストしていませんが  Join(データ配列) で一旦各配列を結合して、再度Chr(10)を区切り文字として分割してはどうですか?

関連するQ&A

  • 二次元配列の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

  • 動的配列の後始末?

    以下のサブルーチンで、lines()と動的配列を定義して、Splitでデータを入れたのですが、このサブルーチンが終了すると、lines()はデータも含めて解放されるのでしょうか? 極端な話、1億回このサブルーチンを呼ぶと、メモリーリークするのでしょうか? それと、VB6やVB.NETでは、For文・For Each文のどちらを使う方が良いのでしょうか? Sub test() Dim lines() As String lines = Split(Data, vbCrLf, -1, vbBinaryCompare) Dim i As Integer For i = LBound(lines) To UBound(lines) MsgBox ("for=[" & lines(i) & "]") Next i Dim s As Variant For Each s In lines MsgBox ("for each=[" & s & "]") Next 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 どなたかご指導をよろしくお願いいたします。

  • エクセル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 のFor Each ・・・ Next について

    配列に数字(特段数字でなくても)入れたいのですが、以下のように書きました。 Sub test() Dim x As Variant Dim m(1 To 10) As Integer For Each x In m x.Value = 100 Next Stop End Sub Stopでとめてmを確認するとすべて0です。どうしてなのでしょうか。 配列ではなく Sub test() Dim x As Variant For Each x In range("a1:a10") x.Value = 100 Next End Sub とするとA1:A10には100が入ります。 この差がいまいちわからなくて、 もちろんFor ・・・ Nextで簡単に入れられるのは承知しています。 補足ですが また最初はx.valueの.valueをつけていなかったのでセルにも反映されませんでしたが.valueをつけると入りました。

  • VBAの配列

    VBAの配列の処理でこまっています。 dim test as Variant test = Array( _ Array("Aさん", 65, 70, 45), _ Array("Bさん", 80, 10, 90)) とした成績データがありまして、あとから(定義の段階でなく)、"Cさん", 70, 70, 75をtest変数に追加したい場合、どのようにすればよいのでしょうか? また、これ(test)を戻り値にした場合、正しく左辺値にはいるのでしょうか?オブジェクトの解放などの問題も知りたいです。 function seiseki () as variant ... 上の処理 seiseki = test end function ...  dim cp as Variant cp = seiseki() 'cp変数にコピーされるのでしょうか?

  • 配列の個数を数えたい

    Dim ar As Variant ar = Split(moji, "/") '配列に格納 for i = 0 to arの[配列の最大数] next [配列の最大数]の部分がわかりません。 たしか、「b」で始まって、「d」で終わり、中に「o」が入ってたような気がします、、、 (自信ないです) どなたかこれだけのヒントでわかる方いらしたら ご解答よろしくお願いします。

  • VBAでオブジェクトの配列を使用するには?

    Access2000のVBAでプログラムをしています。 VBAでクラスを作成し、プロシージャの呼び出しの引数に使用しています。あるプロシージャで、クラスの配列を作成し、呼び出し元へ返したいと思っていますが、うまくいきません。これは、できないものなのでしょうか? ---(呼び出し側) Dim objA as clsA, aryB as variant ' 「aryB as Object」でもダメ procB objA, aryB Dim objTemp as Variant ' 「objTemp as Object」でもダメ For Each objTemp In aryB ' ここでエラー「オブジェクトが必要です」 MsgBox objTemp.AAA Next --- --- (プロシージャ側) Public Sub procB(ByRef objA as clsA, ByRef aryB as Variant) Dim aryRet() as clsB, lngI as long For lngI = 0 To 10 Redim Preserve aryRet(lngI) Dim objTemp as clsB Set objTemp = New clsB Set aryRet(lngI) = objTemp Next aryB = aryRet End Sub やりたいことは、プロシージャ側でオブジェクトの配列を作成し、呼び出し側に渡して、呼び出し側で、「For Each・・・Next」で回したいと思っています。 どのようにしたら実現できるか、知っている方、よろしくお願いします。

  • 配列

    エクセルvbaなのですが Sub test() ' 配列 Dim arr() As Integer= {0, 1, 2, 3, 4, 5} ' 抜き出した要素を格納するための変数 Dim i As Integer ' すべての要素について繰り返す For Each i In arr Console.WriteLine (i) Next End Sub これって何でエラーになるのでしょう? Dim arr() As Integer= {0, 1, 2, 3, 4, 5} でエラーになりますが、なぜだかわかりません。

  • Excel vba 配列内の最大値を求めたいです。

    Excel vba をはじめて1ヵ月程度の初心者ですが、すいません質問させて下さい。 動的配列というのでしょうか? その配列の中の最大値を求めたいのですが、よくわかりません。 アクティブシート内の図形で最前面以外の図形を消去しようと思ってます。 マクロで最大値の取得ができないので、暫定的にシートに計算させてしまっているのですが、マクロ上で最大値を求める方法がわかりません。 Sub testSZ() Dim Num As Integer, Sum As Integer, Shp As Shape, Ary() As Variant, Mxm As Long '++++++++++↓アクティブシート内の図形をカウント:=Sum Sum = 0 For Each Shp In ActiveSheet.Shapes Sum = Sum + 1 Next Shp '++++++++++↓配列の数を決定 ReDim Ary(1, Sum) '++++++++++↓配列に図形と図形のZオーダーを設定 Num = 0 For Each Shp In ActiveSheet.Shapes Shp.Select Set Ary(0, Num) = Shp Ary(1, Num) = Selection.ShapeRange.ZOrderPosition Num = Num + 1 Next Shp '++++++++++↓配列内のZオーダー最大値を取得 Mxm = Application.WorksheetFunction.Max '++++++++++↓最前面の図形以外を消去 Num = 0 Do If Mxm > Ary(1, Num) Then Ary(0, Num).Delete End If Num = Num + 1 Loop Until Sum = Num Erase Shp End Sub Application.WorksheetFunction.Max[] の[]にAryやAry(1,Num)をやってみたりしたのですが、 できないです。 どなたか御教授おねがい致します!!

専門家に質問してみよう