• 締切済み

エクセルVBAで平均値を求める方法

みなさん教えてください。 今、実験で測定したデータの整理を行っています。 そこで、教えて頂きたいことがあります。 下記のようなデータの整理を行っています。 今行いたいことは、下図のようなプラスとマイナスの数値(図ではA・B・Cエリアと区別)に おける各エリアの個別の平均値をマクロで求めたいと思っています。 <データの詳細> ・データ数は全部で約400個 ・データは、下図のようにプラスの数値のあとにマイナスの数値がくるようになっています。 みなさんマクロで求める方法(構文)を教えて頂けないでしょうか。 よろしくお願いします。

みんなの回答

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

質問者は、戻らないのかもしれませんが、#4のマクロをもう少しそぎ落としてみました。数式と違う部分は、空白があっても、誤動作しません。文字に関しては、同じ仕様です。 '*書きだし場所は変更出来ます。 '// Sub EachAverage2()  Dim rng As Range  Dim i As Long  Dim iStr As Long, iEnd As Long  Dim dSum As Double, cnt As Long  Set rng = Range("A1", Cells(Rows.Count, 1).End(xlUp)) 'A1とCells(Rows.Count, 1)の1 の列は合わせること。  rng.Offset(, 1).ClearContents  iStr = rng.Cells(1).Row  iEnd = rng.Cells(rng.Cells.Count).Row '隣の列は一旦クリアされます。  Application.ScreenUpdating = False  '*  For i = iStr To iEnd   If Val(Cells(i, 1).Value) > -1 Eqv Val(Cells(i + 1, 1).Value) > -1 Then    dSum = dSum + Val(Cells(i, 1).Value)    cnt = cnt - (VarType(Cells(i, 1)) = vbDouble)   Else    dSum = dSum + Val(Cells(i, 1).Value)    cnt = cnt - (VarType(Cells(i, 1)) = vbDouble)    Cells(i, 2).Value = dSum / cnt '*    cnt = 0    dSum = 0   End If  Next i  Cells(i - 1, 2).Value = dSum / cnt '*  Application.ScreenUpdating = True  Set rng = Nothing End Sub

  • MackyNo1
  • ベストアンサー率53% (1521/2850)
回答No.6

数式で計算するなら以下のような一覧表を作成するのが簡単かもしれません(添付図参照)。 C2セルに「1」と入力 符号の切り替わりの行番号のC3セル(下方向にオートフィル) =MIN(INDEX((INDEX($A$1:$A$400,C2):$A$400*(-1)^ROW(A2)>0)*1000+ROW(INDEX($A$1:$A$400,C2):$A$400),)) 平均値のD2セル(下方向にオートフィル) =IF(COUNT(A:A)<C2,"",AVERAGE(OFFSET($A$1,C2-1,0,C3-C2,1))) 数式が複雑になるので処理しませんでしたが、符号の切り替わりの行番号の最後の表示したいくない部分は、IF関数や条件付き書式で表示しないような設定にもできます。

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

#4の回答で、数式に触れましたので、数式は、あまり得意ではないのですが、数式も書いておきます。 B1 から、=IF(ROW(A1)=1,0,IF(OR((A1>-1)<>(A2>-1),ISBLANK(A2)),ROW(),""))  をフィルダウン・コピー(トップのフィルハンドルをダブルクリック) C2 から、=IF(B2<>"",AVERAGE(INDEX(A:A,MAX($B$1:B1)+1,1):INDEX(A:A,B2,1)),"")  をフィルダウン・コピー(トップのフィルハンドルをダブルクリック) つまり、マクロで数式を貼り付けてもよいかもしれませんね。

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

データに数値のないものが含まれるエラー処理を含めています。 計算の排出先は、* がついている部分ですから、列の隣なら、.Cells(i, 2).Value ですから、この2 を換えてあげればよいです。また、Celltop のセルの先頭を最初に設定すれば、場所を変えることが出来ます。 Average 関数は使いませんが、Average関数の文字に対するの考え方を反映するようにしました。 ただ、これは、あくまでも、VBAマクロという前提で、並んでいる環境なら関数でも可能なような気がします。 '// Sub EachAvarages()  Dim CellTop As Range, rng As Range  Dim i As Long, cnt As Long  Dim dSum As Double  Dim F As Long, iFlg As Integer    Set CellTop = Range("G5") 'セルの先頭  Set rng = Range(CellTop, Cells(Rows.Count, CellTop.Column).End(xlUp))  If Application.CountA(rng) = 0 Then MsgBox "データがありません。", 48: Exit Sub  'rng.Offset(, 1).ClearContents '右隣の列のデータ削除(必要に応じて外してください)  Application.ScreenUpdating = False  With rng   For i = 1 To rng.Rows.Count   If F = 0 Then F = i: iFlg = Val(Cells(i, 1)) > -1    If i = rng.Rows.Count Then    If VarType(.Cells(i, 1)) = vbDouble Then cnt = cnt + 1     .Cells(i, 2).Value = (dSum + Val(.Cells(i, 1).Value)) / cnt '*     Exit For    End If    If VarType(.Cells(i + 1, 1)) = vbDouble Then     iFlg = Val(.Cells(i, 1).Value) > -1     If VarType(.Cells(i, 1).Value) <> vbDouble Then iFlg = 0     If CInt(Val(.Cells(i + 1, 1).Value) > -1) <> iFlg Then      dSum = dSum + Val(.Cells(i, 1).Value)      cnt = cnt + 1      .Cells(i, 2).Value = dSum / cnt '*      dSum = 0: F = i: cnt = 0     Else      dSum = dSum + Val(.Cells(i, 1).Value)      cnt = cnt + 1     End If    Else      dSum = dSum + Val(.Cells(i, 1).Value)    End If   Next i  End With  Application.ScreenUpdating = True  Set rng = Nothing: Set CellTop = Nothing End Sub

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

いまこの質問を見ると画像が真っ黒で、どういうデータか判らないよ。 一般に (1)例データは質問文にテキストで作成するようにしてほしい。 (2)質問者は質問をOKWAVEに上げた後、読者の立場で一度照会してみてほしい。 ーー 平均値を求める方法は (1)エクセル関数で求める AVERAGEIFやSUMIF 質問者にはこれで良いのでは。 (2)エクセル関数をVBAで使う方法 (3)各行のデータをとらえて計算していくとき データ数と そこの行までの合計を足していく、最後に合計を件数で割る 方法(有名な初歩的アルゴリズム)と在る。 ーー 本件も画像が見えないので答えられないが、クラス(A,B,Cか)分けと符号が尋常ではないようだから、 それを新しい列に普通のデータに作れば、後はエクセル関数利用などで簡単でしょう。 計算だけなら、VBAでやる意味は余り無いと思う。 VBAを使う理由を認識できているか疑問。

回答No.2

お遊びで参加 数式のみなんだけど(^^;) Sub Macro1() Application.ScreenUpdating = False    Dim 終わり行 As Long    終わり行 = Cells(Rows.Count, 1).End(xlUp).Row        Range("B:D").Insert    Range("B1") = Range("A1").Value    Range("B2:B" & 終わり行).Formula = _        "=IF(SIGN(A1)=SIGN(A2),SUM(A2,B1),A2)"    Range("C1") = 1    Range("C2:C" & 終わり行).Formula = _        "=IF(SIGN(A1)=SIGN(A2),SUM(1,C1),1)"        With Range("D1:D" & 終わり行)        .Formula = _        "=IF(SIGN(A1)<>SIGN(A2),B1/C1,"""")"        .Value = .Value    End With        Range("B:C").Delete     Application.ScreenUpdating = True End Sub

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.1

A列にA1からデータが並んでいる。 sub macro1()  dim ha as range  dim i as integer  dim s  s = array(">=0", "<0")  application.screenupdating = false  range("1:2").insert shift:=xlshiftdown  range("B:B").insert  range("A1") = "h"  for i = 0 to 1   if application.countif(range("A:A"), s(i)) > 0 then    range("A:A").autofilter field:=1, criteria1:=s(i)    for each ha in range("A2:a" & range("A65536").end(xlup).row).specialcells(xlcelltypevisible).areas     ha.range("B1") = application.average(ha)    next   end if  next i  activesheet.autofiltermode = false  range("1:2").delete shift:=xlshiftup  application.screenupdating = true end sub

関連するQ&A

  • VBAでグラフを作成する方法

    みなさん教えてください。 今デジタルオシロで測定した下記のようなデータを、添付図のように正弦波で表していますが、 図中の赤枠部分だけをデータから抽出してグラフで表したいと考えています。 方法は、赤枠部分のようにグラフY軸の電圧値範囲を指定して、指定した範囲のデータ抽出し ようと色々試してみましたがうまくいきませんでした。 マクロを使用して、自動的にデータを抽出する方法はないでしょうか。 マクロの構文を教えて頂いたらうれしいです。 宜しくお願いします。 <デジタルオシロで測定したデータ> ※データ総数:450個程度 時間s 電圧V 0 0.03626667 0.0002 0.037975 0.0004 0.035025 0.0006 0.03514167 0.0008 0.03781667 0.001 0.03830833 0.0012 0.03346667 0.0014 0.03460833 0.0016 0.03616667 0.0018 0.0342 0.002 0.03035 0.0022 0.03088333 0.0024 0.032775 0.0026 0.02990833  ・    ・  ・    ・  ・    ・

  • ExcelのVBAについて質問なんですが。VBAに関してはまったくの素

    ExcelのVBAについて質問なんですが。VBAに関してはまったくの素人です。 大学の実験でLEDの温度変化の実験をしています。実験器具はデータロガーGL800を使用しています。そのデータロガーで測定した温度をExcelにリアルタイムに書き込んでいってるのですが、その際更新されていく最高温度のみを別に表示させたいのですが、どのようなVBAのマクロを使えばいいのか教えてください。

  • 計測器の測定データをエクセルに取込み

    みなさん教えてください。 今電子温度計の測定データをRS232経由でエクセルに取り込むマクロを 作成しています。 一定間隔にデータ取り込むマクロは完成したのですが、今度はUSBタイプ の外付けテンキーボードのエンターキーを押してデータを取り込みたいと思 っているのですが方法がわかりません(マクロの構文をどう変更すればよい かわかりません)。 みなさん教えてください。お願いします。

  • エクセル

    実験をしているのですが、物体の重さを量っていまして数値を機械がエクセルに入力するようになっていたのですが、数値が一つのセルに入力されていたので区切りを入れたいと思ったのですがやり方がわかりません。 例 388.43388.92→388.43 388.92 このようにデータを行か列で区別していきたいです。 データが一万個ぐらいあるので何か効率のいいやり方があれば教えてください

  • エクセルのVBAで、音をならす方法

    こんばんは。私はエクセル2000を使用しています。 現在やろうとしていることは、 実験の測定データをエクセルに取り込み(測定データは文字列としてエクセルに取り込まれます)、D列の数字が100以上になったら音をならして知らせるようにしたいと考えております。 それで、以下のマクロを組んでやってみました。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Column = 4 Then If IsNumeric(Target) And Target.Value > 100 Then Beep    MsgBox "範囲外です" End If End If End Sub しかし、If IsNumeric(Target) And Target.Value > 100 Thenのところで、型が一致しませんとエラー?がでてしまいます。 まだ、VBAを勉強しはじめて2週間くらいなので、なにぶんわからないことだからで、もしわかる方がいらしたら教えてください。

  • エクセルVBA 図のコピー&ペーストの方法

    いつもお世話になっております。 VBAを学習中の者です。 今回は図のコピー&ペーストについて教えてください。 (作成中の表:Excel2010を使用) (1)Sheet1:帳票一覧  A列:NO B列:氏名 C列:写真 D列:プロフィール  のような表を行毎に作成しています。   (2)Sheet2:個別帳票雛形  マクロの実行により、雛形シートをコピーして、配列に格納したデータをコピーしたシートの指定箇所に転記 簡単に説明するとこのような作業を行いたいと考えています。 現在写真以外の転記については問題無く処理が行えました。 (仕様) 1.写真には01,02,03,04・・・・・と名称を付けております。 2.転記先シートのB4~C12セルを結合して写真の貼付エリアとしています。 3.転記時に画像データのサイズを自動調整(又は貼付エリアに見栄えよく貼れるように数値を指定) 4.貼付エリアの中央にくるように配置 以上を行いたいと思っております。 どうぞよろしくお願いします。 、

  • EXCELにてローパスフィルタを作成する

    実験の測定データをEXCELでデータ整理しようと考えております。データ整理のためローパスフィルタをかけたいのですが、具体的にどういった式、もしくはEXCELの機能を使用したらいいのでしょうか?デジタルフィルタが良く分からないのでよろしくお願いします。 ちなみにローパスフィルタは1000Hzをかけたいです。

  • Excelで2つの表を1つにまとめるには?

    下図のように、2種類の表があります。 これを、1つの表にまとめ、日付順に並ばせたいのですが マクロを使わないで数式だけで行うにはどうしたらよいでしょうか。 データを手で打ち直すことは考えていません。(実際にはもっと項目が横に長い表です。) 「コピー→貼り付け→並び替え」という作業も考えていません。 ・下図では、データが「A組」では4つ、「B組」では5つとなっていますが、  実際には20個程度のデータ(数は不定)が入ります。 ・また、文字データ(名前、教科)と数値データ(得点)とが混在しています。 ・項目に当たる部分は両方の表とも同じものが入ります。 ・日付、名前は重複する場合があります。

  • エクセルで…関数かマクロか?

    エクセル2007を使っています。 3列のシートがあるとしますね。 それぞれの列は、「A 現金残高」、「B 収入」、「C 支出」とします。 たとえば、3行目から数値を入れるとします。 普通ならば、B3 (収入)のセルに 1000(円) と数字を打ち込めば、 A3 (現金残高)のセルに同じく 1000が入るよう、=B3 とすればいいと思います。 同様に、C3のセルに1000と入力すれば、 A3のセルには -1*(C3) とすることで、現金残高が収入と支出によって、 プラスマイナスされるようにし、あとで各列を∑すれば済みますね。 でも、いま僕がやりたいのは、 たとえば現金残高 A3のセルに -1000 と入力すると、自動的に C3のセルに 1000 と 表示され、A3に 1000 と入力すると、 B3のセルに 1000と表示されるようにしたいのです。 要するに、現金残高に入力した数値がプラスかマイナスかによって、 数字が表示されるセルを個別に指定し、指定したセルに計算結果を表示させたいわけです。 IF関数で、数値のプラスマイナスは判断できますが、任意のセルを指定させる方法が わかりません。 「もし…だったら 『任意のセルに』○○せよ」  というような指定はできるのでしょうか? もしくは、マクロを使わないとできないのでしょうか? いろいろサイトも調べてみましたが、力不足で回答にたどり着くことができませんでした。 よろしくご教授お願いいたします。

  • エクセルマクロ(VBA)の変数について教えてください。

     仕事でエクセルを利用してファイルを作ることが多いのですが、関数とマクロに課題のある者です。  マクロはそんなに高度で複雑なものが現状、必要でないので記録マクロで事足りていますが、私のやり方は  1.手順を記録  2.マクロの実行  3.ステップイン機能でステートメントの動作を見る  4.無駄な構文を削除  5.エラー(デバッグ警告表示)修正  6.日々替わる取り扱いファイル、シート名をそこだけ置き換えて汎用性を持たせている。  7.さらに動作を加えたい時は新しいマクロ記録で構文を記録し、ベースマクロに構文を追加している  8.日々更新変動されるファイルは情報量の余裕をみて、ファイルが想定を超えないように作っている。  9.記述式マクロ(VBA)が十分出来るスキルが乏しい  と言うのが私のレベルですが、参考書、テキストを読んでいると必ず、『変数』Dimスペルというものが出てきます。この意味がもう一つよく分からないので、ツール→オプションのダイヤログボックス編集で『変数の宣言を強制をする』を外しています。  変数は実行の都度変わる値を扱ったり、代入すると言うことは何となく分かるのですが、完全に理解できてないので、(記述が分かりにくい)そこから前に進めません。  サンプル例はありますが、詳しく解説しているものが少ないです。『何故、こうなるか?』というのが抽象的な説明です。  『変数宣言を強制』にチェックを入れた場合、今まで、チェック無しで作ったマクロファイルは動作しませんか?  たまに自動メンバー表示機能から構文を挿入しますが、個々のプロパティやメソッド、コレクションなど記述構文は英語ですが、これを日本語に置き換えて理解できるようにしたいのですが、皆さんはどのようにされたのですか?  

専門家に質問してみよう