• 締切済み

EXCEL VBA 2次元配列に格納された値の最小値を調べたい

いつもお世話になっております。 ブックAのマクロからブックBのデータを以下のように配列に入力しています。 myData = Workbooks("ブックB.xls").Worksheets("temp").Range("A1:G1000") 配列myDataに格納された値の最小値を調べたいのですが、myDataに格納されているデータは数値だけではなく、日付、時間も含まれます。 数値のみが含まれるのはmyDataの3~6列です。 myDataが数値のみの配列の場合、 WorksheetFunction.Min(myData) で配列全体を調べることが出来るのは分かったのですが、今回の場合は日付、時間が含まれるため「型が一致しません」というエラーがでて、最小値を求めることが出来ませんでした。 WorksheetFunction.Minを使って特定の列(今回の場合3~6列)に格納されている数値の最小値を調べることは出来るのでしょうか。 3~6列を別の配列に格納すればそれで解決なのですが、出来れば変数をmyDataだけで済ませたいと思っています。 また、WorksheetFunction.Minを使わないでfor文を使う方法も考えつきましたが、できればWorksheetFunction.Minなどの関数を使ってスマートにやりたいと思っています。 よろしくお願いします。

みんなの回答

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

こんばんは。 >関数を使ってスマートにやりたいと思っています。 よく質問で、「スマート」という言葉が出てきますが、私は意味が良く分からないです。「スリム」というなら意味は分かりますが、それは、良いときと悪いときがあります。 コードに合理性があって、エラーを吐かなければそれで良いとすればよいと思います。ベテランの人のコードは、単に論理性と合理性の追求だけであって、それ以上のものを求めているわけではありません。しょせん、VBAマクロの、マクロという意味は、タスクを実行するという意味を含んでいるので、仕事をしなければマクロではない、という結果論でしかありません。それと、関数も、中身は人の作ったプログラミングです。単に、作られた言語の違いでしかありません。 コードですが、myData で、配列を使うのでしょうか? Dim r As Range Dim ret As Double Set r = Workbooks("ブックB.xls").Worksheets("temp").Range("C1:F1000") ret = WorksheetFunction.Min(r) で良いと思うのです。 それに、時間であろうが、日付であろうが、日付型は、すべて数値型ですから、それ自体ではじかれることはありません。時間や日付のセルを省くなら、ループで探すしかないと思います。範囲内に、エラー値があれば、プロパティエラーが発生します。 「型が一致しません」 そのエラーは、おそらく、基本的に、配列の変数の型の問題だろうと思います。 ワークシートの2次元配列を受けるなら、 Dim myData As Variant ということです。

center69
質問者

お礼

回答、ありがとうございます。 私の稚拙な文章で不快な思いをされたようで申し訳ありませんでした。 myDataで配列を使う理由は、今回の質問と関係ない部分でループ処理をするためです。 ループ内でいちいちブックBへアクセスすると速度低下を招くと考えたからです。 今回の質問の、2次元配列に格納された値の最小値を知りたいというのは私がやりたいと思っていることのごく一部分に過ぎません。 hana-hana3様へのお礼でも書きましたが、私はプログラミングに対する考え方から直さないといけませんね。 お騒がせいたしました。

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

>スマートにやりたいと思っています。 myData をどのように利用するのか解りませんが、スマートにやりたいと言うなら、意味の異なる部分まで取り込まない事だとおもいます・・・。 myMin = WorksheetFunction.Min(Workbooks("ブックB.xls").Worksheets("temp").Range("C1:F1000"))

center69
質問者

お礼

回答、ありがとうございます。 WorksheetFunction.Minを使って特定の列に格納されている数値の最小値を調べることが出来るかどうかが知りたかったのですが、どうやらそういう方法はないようですね。 スマートにと言うなら、hana-hana3様が仰るように余計なものを取り込まなければいいんですよね。 質問をする前に、私はプログラミングに対する考え方から直した方がいいようですね。 申し訳ありませんでした。

関連するQ&A

  • 2次元配列への格納方法について

    こんにちは。 FILE *fp; SIZE 1024; int n; char Buf[1025]; while((n = fread(Buf,1,SIZE,fp)) != 0){ } というように、fread関数を用いて1024バイトずつ配列Bufへ格納しています。 以下に示すようなことを行う場合、どのように記述すればよいのでしょうか? B:バイナリデータ T:数値 TBBBBBBBBB・・・・・・B←1024バイト目 TBBBBBBBBB・・・・・・B ・ ・ ・ ・ TBBBBBBBBB・・・・・・B というように、配列内に格納したいと思っています。 Tは、テキストデータで1,2,3・・・・100という整数型を格納。Bは、バイナリデータでfread関数から取得したバイナリデータを格納します。 なぜ、Tを格納したいかといいますと、どのバイナリデータを指しているか?を判別するためです。 上記のようなことを行うためには、2次元配列を使用すればよいのでしょうか? 例:char Buffer[100][1025]

  • VBA 配列に格納した値の平均のやり方についてお教え願います

    いつもお世話になります。 配列に格納した値の平均のやり方についてお教え願います。 現在、実験測定データの移動平均(下記avg(x,1))を計算をしたいのですが、 配列に格納した値の平均が思うように計算できず困っております。 a =Range("A1:A20000")‘測定データを配列に格納 avg(x, 1) = Application.WorksheetFunction.average(a(x, 1), a(x + 5, 1)) という記述方法ではa(x, 1)とa(x + 5, 1)の2点の平均になってしまいます。 これをa(x, 1), a(x+1, 1),a(x+2, 1),a(x+3, 1) ,a(x+4, 1) ,a(x+5, 1)の5点の平均が計算できる記述方法はないでしょうか? ○実際の式は下のようなもので移動平均の平均区間yも変化します。 Dim avg(1 To 20000, 1 To 1) -前式省略- For y = 1 To 20000 -途中式省略- a =Range("A1:A20000")‘測定データを配列に格納 For x = 1 To 20000 avg(x, 1) = Application.WorksheetFunction.average(a(x, 1), a(x + y, 1)) ‘↑これでは2点の平均値になってしまいます。 Next -途中式省略- Next -後式省略- ○Range(“B1”)=AVERAGE(A1:OFFSET(A1,y-1,0)) Range(“B2”)=AVERAGE(A2:OFFSET(A2,y-1,0))  ・・・ というふうにセルに一つずつaverage関数を入力すれば移動平均も計算できるのですが、繰り返し回数が多いため、計算に非常に時間がかかります。そのため上記配列を利用したもので計算したいと思います。 ○ ネットでヒントを見つけたのですが↓ Set ran = Range(Range("A1"), Range("A1").End(xlDown)) Range("C4").Value = WorksheetFunction.average(ran) こう記述すればある範囲内の平均を求められるようですが、 Set ran= 以降の部分をRange(***)ではなく、 Set ran = (a(x, 1), a(x + y, 1)) ←a(x, 1)~a(x + y, 1)まで、というイメージですが・・・ というふうに範囲を配列で表すやり方を教えて頂けるだけでも結構です。 excel2003です。 以上、よろしくお教え願います。

  • 《エクセル2000》配列数式とMIN関数を使い、最小値を出したいのですが

    いつもお世話になっております。 配列数式とMIN関数を使って最小値を出す作業をしていますが、最小値は0.3なのに0.0と返って来てしまいます。 条件は「A列が1で、B列が数字だったら」なのですが、B列には空白も入っています。 B列の空白のセルは、ISNUMBER関数でチェックするとFALSEが返ってくるのですが、もしや空白を0とみなしているのでしょうか。 COUNTIFのMIN版と言いますか、条件つきで最小値を出せる関数があればいいのですが…原因と対策をご存じの方、どうかご教示を。

  • VBAでエクセルのいくつかの表を同じ配列に格納する

    VBA初心者です。 調べてみましたがどうにも情報に行きあたらなく、ご質問をさせていただきます。 添付のようなエクセル上の同一シート上にある3つの表をコピーし、VBAで同じ配列の各列として取り込みをしたいと考えております。 大分類、中分類、小分類のそれぞれの行は同じもののそれぞれの内容を記載しており、 できればこれらを同じ配列の1列目、2列目、3列目に格納をしたいと思っております。 これらの表が1つの表にまとまっていれば、 Dim 配列(1,10) as Variant 配列 =range("A1:C10") で事足りると思うのですが、別々のためこの方法がとれません。 セル指定で行うことも考えましたが、データが10万行を超える場合もあるため、できれば避けたいと思っています。 各表を指定し、配列の1列目、2列目、3列目に一括して代入をご存じでしたらら、どうぞ教えていただきたいと思います。 どうぞよろしくお願いします。

  • VBA(多くの数値データの最小値5つを格納する方法)

    VBA(多くの数値データの最小値5つを格納する方法) 現在テキストファイルの数値データを取り出し最小値5つを書き出す動作をVBAで行うつもりでいます。 例  5    9    33    11    1    0.3    0.02     ・     ・     ・     ・ といった形の数値データ行がテキストファイルに存在します。 今現在すべての数値データを格納してエクセルに書き出しそれを並び替え最小値5つ(0を除く)を見て作業を行っております。 この作業をより効率化するために、VBAを用いて0を除いた最小値5つをエクセルシートに書き出すようにしたいのですが、VBAの知識が足らず対策が思い浮かびません。 ・VBAで行いたいこと(わからない部分) 格納するデータを5つに設定して、数値データを順次読み込み最終的に数値データ群の最小値5つ(0を除く)を配列に格納している状態にしたい。 初歩的かもしれませんが、ご回答お願いいたします。

  • VBAの一次元配列から二次元配列へ

    A列にa1~a100まで数字が入ってます。 それを、b1~b5,c1~c5,…省略 u1~u5までに、データを 5行ずつ移したいのです。 b1にはa1、b2にはa2の値を、u5にはa100の値を入れたいのです。 マクロの自動記録?を使うとできることはできるのですが…。 一次配列→二次配列で、出来ると聞いたことがあるのですが。 ※VBAは全くの初心者です。 コードに説明もつけてくださるとすごく助かります。 どうかよろしくお願いいたします。

  • Excel.Rangeで取得した値を配列に格納するには?

    プログラミング初心者です。 VB.NET でExcelからデータを取得したのですが、配列等に格納したいのですが、うまくできなくて困っています。どなたか教えてください。 例)以下のデータを取得する場合 セルA(列)1(行)からA5まで セルB1からB5まで セルC1からC5まで Dim xl_APP As Excel.Application Dim xl_Book AS Excel.Workbook Dim xl_Sheet As Excel.Seets = xl_Book.Worksheets Dim xl_W_Sheet As Excel.Worksheet = CType(xl_W_Sheet.Item(1),Excel.Worksheet) 中略 Dim range_data As Excel.Range Dim i Integer Dim j Integer Dim strCel As String For i = 1 To 5 For j = 1 To 3 range_data = CType(xl_W_Sheet.Cells(i,j),Excel.Range) strCel = CStr(range_data.Value)  ↑String型変数に格納していますが、多次元配列?に格納して取り出せるようにしたいのですが、どうしたらよいのでしょうか? Next Nest <range_dataに格納されるデータ> A1:氏名 B1:学年 C:1 年齢 以下同上 ・・・・のように取り出したいと考えています。 よろしくお願いします。

  • Excel VBA 値取得について

    お世話になります。 どなたかお力をお貸しください。 Excel2003 VBAでプログラムを組んでおり、エクセルのシートをデータベース代わりに利用しています。 複数のブック散乱している10万個近くのテキストボックスの値を、 「A」というブックの「シート1」のセルに格納して行きたいと思っております。 値の格納方法としては、「A」ブックの「シート1」の セルA1からA2、A3…A列最終行(6万強)まで縦の並びにデータを格納していきます。 ただし、「シート1」に格納したい値は10万個近くあるので、 A列だけでは足りなくなります。 A列の最終行まで値を格納し終えたら、自動的にB列に移動して、 セルB1からB2、B3…B列最終行(6万強)という遷移させていきたいのです。 A列のみに格納していくのであれば、理解できるのですが、 自動遷移がわかりません。 For i = 0 To 最終行(6万強) シート1.Range("A" & i) = 参照元 Next i よろしくお願いします。

  • エクセルで最新の最小値をだしたいのですが、、、

    エクセルで、最新の最小値をだしたいのですが、 MIN関数で最小値はだせるのですが、 最小値が同じものが複数あり、 一番新しいデータ入力日の最小値を 表示したいのでずが、 一番古いデータ入力日のものが 最小値として呼び出されてしまいます。 OR等を使って式を入力してみたのですが、 エラーがでてうまく値がだすことができません。。。 データは、C1からZ1までデータ入力日がはいっています B2からZ50まで数字がはいっています。 それぞれの行ごとの最小値をA列に表示させたいと思っています。 さらにそのあと、B列に、最小値のデータ入力日も表示させたいと 思っています。 ↓A2セルには、”10”  B2セルには、”3/11”と表示させたいのですが...  =MAX(MIN($C2:$Z2)*$C1:$Z1) こんな感じで作ってみたのですが、VALUEのエラーが でてしまいます。。      A列  B列  C列  D列  E列・・・ 1行目          2/10 3/10  3/11・・・ 2行目          10    15  10 ・・・  3行目          20    25  30 ・・・ ・ ・ ・ どなか分かる方どうか教えてください。 よろしくお願いします。

  • VBAの配列の格納について

    エクセルのVBAで、セルのデータを配列に格納するスピードを向上したいと思います。 例えば、A1~A10000のセルにデータを書き出す場合、 For 行番号 = 1 To 10000 Cells(行番号, 1).Value = 1 Next よりも、一旦、配列に書き込んだ後、一気にセルに書き込んだ方法が早いのですが、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = 1 Next Range("A1:A10000").Value = HAIRETU() 今度は、A1~A10000に書き込んだデータを、再度、配列に格納する場合、 For 行番号 = 1 To 10000 HAIRETU(行番号, 1) = Cells(行番号, 1).Value Next とすると時間がかかるので、 HAIRETU() = Range("A1:A10000").Value というような処理をしたいのですが、うまくいきません。 よい方法がありましたら、ご教授ください。 よろしくお願いします。

専門家に質問してみよう