• ベストアンサー

エクセルVBA作成に関して

VBA作成についてお願いいたします. たとえば各セルに以下のような数値があるとします    A   B  C 1 150 2 2 145 6 3 237 7 4 254 6 5 結果としてC5セルに A1*B1+A2*B2+A3*B3+A4*B4の計算をし表示するVBAを作りたいと思っています. このくらい少ない場合はよいのですが,列が多くなるといちいち計算式を書くのは大変ですし,このあたりをVBAで作れないかと悩んでいます. つまり 例表示すると Range("A1").Value とあった場合("A1")の1を2,3,...と増やしていく(あるいは減らしていく)VBAは作成可能ですか? どうも調べたかぎりでは見あたらないようなので. この表現で質問の意図は伝わったでしょうか? ご存じの方よろしくお願いいたします.

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

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

こんにちは。 やはり、ほぼ解答が出てしまいましたね。 私の入門編の回答は、とっておきます。 もう、ここらで十分だとお思いなら、このまま締めてしまってもかまいません。 ただ、基本としては、  ・変数の宣言はすること。  ・プロシージャ名や変数には、ある程度、名前の付け方があって、暗黙のルールがある。*  ・仮に、デフォルトプロパティでも、オブジェクトのプロパティの省略はしないこと。  ・オブジェクト(Range型等)の取得のそのプロセスに、Select は必要ない。 *ただし、Excel VBAでは、変数の命名規則(LNC)を使いすぎると、なんとなく野暮ったく感じます。 ということです。そういうルールを無視しても、VB系はコーディングが可能だということですね。VBAを知らない人に、VBAのコードはこんな風だといっても、何にもなりませんね。出来る人も出来ない人も、志を持ったら、後は、自分自身がどれほど精進していけるかということだと思います。 以下は、私の今の力で書いた実験的なマクロです。 力のレベルというのもヘンですが、このぐらいで、 http://vbae.odyssey-com.co.jp/index.htm Excel VBA エスキパート スタンダードレベル パス だと思っていいと思います。(私は、資格は持っていません。お金が惜しいからです) #2で述べた #単純に見えてそうではありません。VBAで、忠実に再現させるのは、とても難しいです。一般のVBAとは考え方が違うつくりなのです。 というのを再現させてみました。もともとの質問の趣旨のマクロとは、まったく種類の違うものですが、#2で書いたときに、おぼろげながら、こんなコードを頭に浮かべていましたので、一応、書いておきます。これは、入門レベルでは参考にはなりませんが、こういうものも、時に作らないと自分の技術の維持にはならないように思っています。 これは、SUMPRODCUCT 関数を再現しようとして作られたものです。 数式は、このように入ります。たぶん、横の配列には考慮しておりません。 =MYSUMPRODUCT(A1:A4,B1:B4)  これは、横を増やすことが出来ます。 例: =MYSUMPRODUCT(A1:A4,B1:B4,C1:C4) また、こういう式も可能です。 =MYSUMPRODUCT(A1:A4,(B1:B4>3)*1) '標準モジュール '-------------------------------------------------- Function MySumProduct(ParamArray Ary() As Variant)   Dim Art() As Variant   Dim Ar() As Variant   Dim i As Long, j As Long, k As Long, e As Integer   Dim max As Long   Dim n As Long   Dim c As Variant   Dim a As Variant   Dim v As Variant   Dim sbtotal As Variant   Dim mTotal As Double   Dim myfrml As String   Dim arfrml As Variant   Dim x As Variant   Dim m As Integer   Const vbMyError As Integer = 513   On Error GoTo Extra   For Each a In Ary()     If IsError(a) Then       '特殊数式       Err.Raise vbMyError       Ary(e) = a     End If     If StrComp(TypeName(a), "range", 1) = 0 Then       j = UBound(a.Value, 1)     ElseIf VarType(a) = vbVariant Or vbArray Then       k = UBound(a, 1)     End If     If max < j Then       max = j     ElseIf max < k Then       max = k     End If     e = e + 1   Next a   e = 0   ReDim Ar(UBound(Ary()))   For i = 1 To max     For Each a In Ary()       If StrComp(TypeName(a), "range", 1) = 0 Then         Ar(n) = a.Cells(i, 1).Value       ElseIf StrComp(TypeName(a), "variant()", 1) = 0 Then         Ar(n) = a(i)       End If       n = n + 1     Next a     For Each v In Ar()       If VarType(v) <> vbDouble Then         sbtotal = Empty         Exit For       End If       If sbtotal = Empty Then         sbtotal = CCur(v)       Else         sbtotal = sbtotal * CCur(v)       End If     Next v     mTotal = mTotal + sbtotal     sbtotal = Empty     n = 0   Next i   MySumProduct = mTotal   Exit Function Extra: '配列数式の場合   If Err = vbMyError Then     On Error Resume Next     With Application.Caller       myfrml = .FormulaLocal       myfrml = Replace(myfrml, "=MySumProduct(", "")       myfrml = Mid(myfrml, 1, Len(myfrml) - 1)       arfrml = Split(myfrml, ",")       a = Application.Evaluate(arfrml(e))       '配列を1次元に戻す       If UBound(a, 1) > UBound(a, 2) Then         ReDim x(UBound(a, 1) + 1)       Else         ReDim x(UBound(a, 2) + 1)       End If       m = 1       For Each v In a         x(m) = v         m = m + 1       Next v     End With     a = x     On Error GoTo 0     Resume Next   End If End Function

ko_obe41
質問者

お礼

プログラムまで乗せていただいてありがとうございます. ひとつの回答をいただきましたのでこれでクローズしたいと思います. 今回の質問にて自分が気がつかないことがたくさんあることに気づかされました. あらためて,ゆっくりでもよいからVBAの学習を進めていきたいと思います. 回答をくださった皆様にも感謝いたします. それでは失礼いたします.

その他の回答 (5)

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

こんにちは。 私たち、VBAを曲がりなりにも知っている人が、解答を提示することは簡単かもしれませんが、これが何かのきっかけになって、ko_obe41さんが学ぶきっかけになれば良いかなって思っています。 私は、常に、VBAを初めてやってみた頃のことが忘れません。だから、何も知らない人が、いきなりというのは、私には難しいと思います。 私は、プログラミングの経験などまったく知らなかった時に、パソコンスクールで、簡単な足し算のコードを作ってみなさいと言われましたが、そう簡単には出ません。今、棚から、最初のVBAのメモを見つけました。A4の紙に手書きで、日付が、2000/5/29 と書いてあります。その時、自宅には、ExcelもWindowsパソコンもありませんでしたので、頭の中で絵を浮かべて考えました。(笑) 参考本は、FOM(富士通)の本しかありません。もちろん、インターネットで調べるなんて出来ません。 Do While ActiveCell.Value <> "" '条件文 If ~ End If ActiveCell.Offset(1,0).Select Loop という書き方でしていました。 ただ、今の私の目からみて、まったく知らない人が、パソコンがない人が書く内容ではないので、驚きです。なのに、その私が、Excel VBAが、さっぱりわからなくなってしまいました。それでも、少し分かりかけたなって思い、本格的にVBAを勉強したのは、パソコンを購入後の1年経った、2002年に入ってからです。 VBAの学び方は、語学の勉強にも数学の勉強の仕方にも似ています。 数学でいうと、いまどきは、「暗記数学」といわれるのですが、やっぱり、数式と一旦は格闘してみないと技術として向上してこないと思うのです。 私たちが、いきなりMASMのコードを書いてみなさい、といわれても、さっぱり見当が付きません。また、他の言語でも、まったく概念的に知らないものは、私たちに、簡単に作れるとは思わないのです。C言語をよく知らない人が、C言語のポインタを扱えるかとかいうと、見よう見まねでは出来ても、概念的に理解できません。 Office VBAは、Visual Basic 6 をモデルにしていますが、VB系というのは、また、すごく曖昧な内容で、歴史的にいろんなものを受容してきているとは思うものの、宣言をしないままに、Variant 型だけでコードが書けてしまうとか、文字と数値の境目がなく、入れ替わってしまうとか、また、モジュールとプロシージャーの依存性が分かりません。 Excel VBA自体の特殊性としては、  Range オブジェクトとCells の関係,  A1 型と R1C1 型,  Sheet と Worksheet の関係,  Window と Workbook の関係,  Office VBA(共有), Excel VBA(固有), Worksheet(本体),Version4 Macro の複合的な関係,  (この先に、.Net FrameWork が加わるように思います)  DDE と OLE と COM 入門編として、すぐに登場するものもあります。それでつまずいてしまう人も大勢いるのではないでしょうか。その中には、私もいます。今の私は、入門の私に対して、どうあるべきだったのか、と考えてみています。答えを提示してしまうだけではだめだと思うのです。 細かいことを気にしていたら先には進まないし、しかし、そのまま置いておくことも出来ず、必ず、超えるために必要な知識もあります。ここのカテゴリを見ているとVBAを扱う人たちは、それらが曖昧なままの方たちも大勢いますし、それを他人が指摘しても、耳を貸さない人も多いようです。Excel VBAは、C言語でも、Perlでもありませんし、また、Word VBAやAccess VBAですらないわけです。 Excel VBA には、それ専用のVBAのスタイルがあるはずですが、基本(Office 97 VBAが一応のスタートライン)は変わらないと思います。入門の際には、「なぜ」は厳禁ですが、上達してくるに従って、「なぜ」を考えなくてはならないことも多いのです。 入門編でも、同じようなものが、ほとんど全部複合的に出てくるのです。その中で覚えようとしたら、どれかひとつの選択肢を以て、切り捨てて、先に進めていくしかないだろうなっていうのが、私の考えです。しかし、上達にしたがって、それらの違いを明確に覚えていく必要もあるのだと思っています。 また、今回の質問でも、本当にこの問題に自分自身で格闘しようとしたら、初心者は初心者なりに、上級者は上級者なり、なかなか歯ごたえのある問題になると思います。 ご質問者さんが、回答がつけられたあとに、私は、また、私なりの回答をつけます。

ko_obe41
質問者

お礼

丁寧なご回答をありがとうございました. おっしゃる内容に自分では理解できない部分もありますが,とりあえずご指摘のように,初心者なりに取り組んでいきたいと思います. ありがとうございました.

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

こんなの「積和」というもので、質問では、他の目的(条件付き集計)で使われている関数だが、質問の回答に毎日使われる関数でSUMPRODUCT関数がある。 数学・行列などでは初めに学ぶことなんだ。文科系だと少し縁遠いのかな。 >どうも調べたかぎりでは見あたらないようなので. これは調べ方が足りない。 ーー これをVBAで使って Sub test01() Cells(10, "A") = Application.WorksheetFunction.SumProduct(Range("A1:A6"), Range("B1:B6")) End Sub もできる。 ーーー プログラムロジックでやるなら Sub test02() t = 0 For i = 1 To 6 t = t + Cells(i, "A") * Cells(i, "B") Next i Cells(11, "A") = t End Sub 何も難しいことは無い。

ko_obe41
質問者

お礼

丁寧な解説をありがとうございました 例文をあげていただきましたので理解に努めます. 失礼いたします

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

こんばんは。 #2の回答者です。 >#1の方にもお礼を書いたのですが、確認画面まで行くと振り出しに戻ってしまうのでうまいことお礼が伝わっているかが心配です 正しく、読めていますが、今回、システムを改変したのか、掲示板の調子がヘンです。 >とりあえず一人で何とかやってみます 私は、必ず、フィードバックして戻ってきますので、待たせていただきます。 もし、だめでしたら、おっしゃっていただければ、折り返し書きます。 出来れば、教本があると良いですね。技術評論社から、大村あつしさんの『かんたんプログラミング Excel VBA』シリーズは、なかなか良いと思います。 プログラミング、模範解答から、書き換えて作るのが一般的ですが、まったく何もないところからですと、最初でも、かなり難しいです。 それから、入門編では、Range 型、 Cells 型は、どちらが入りやすいかというと、Cells型です。それは、数値を代入できるからです。 一応、こちらは、入門用のコードと、#1さんのスタイルのものを作ってみました。私は、まったく、VBAの知らないところから初めて、5~6年経ちました。

ko_obe41
質問者

お礼

こんにちは 丁寧なご回答をありがとうございました また心強い応援をありがとうございます 推薦していただいた教本を購入してトライしてみます. 時間がかかるかと思いますができあがったらご連絡させていただきます それでは失礼いたします.

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

こんにちは。 #1さんの解答で十分というか、#1さんの数式の作り方は、単純に見えてそうではありません。VBAで、忠実に再現させるのは、とても難しいです。一般のVBAとは考え方が違うつくりなのです。 しかし、今回のご質問は、私が、VBAをほとんど知らない時に、FOMのテキストだけで、作ってみろといわれた種類の内容に近いです。一応、私は、まったく分からないままに、旧式のBasic レベルの内容でしたが、数時間掛かって、初めてコードを書きあげました。 もしも、VBAの練習でしたら、まず、自分自身で挑戦してみたらいかがですか。 練習問題なら、とても良い内容だと思います。 >例表示すると Range("A1").Value とあった場合("A1")の1を2,3と増やしていく(あるいは減らしていく) >どうも調べたかぎりでは見あたらないようなので. これは、初級なので、インターネットでは出てこないのだと思います。 ヒントは、Cells と、For i =初期値 to 最終値 を使います。 (いずれ、誰かが解答は書いてしまうでしょうけれども、たぶん、私がイメージしているものとは違うと思います。) がんばってみてください。それが、自分ひとりで出来れば、たぶん、かなりの才能があると思います。今は、直接の解答はしません。

ko_obe41
質問者

お礼

回答をありがとうございました。 とりあえず一人で何とかやってみます #1の方にもお礼を書いたのですが、確認画面まで行くと振り出しに戻ってしまうのでうまいことお礼が伝わっているかが心配です #1,2の両方の方々にお礼申し上げます

  • izmlz
  • ベストアンサー率55% (67/120)
回答No.1

VBAでなくても↓の関数でお望みの計算が可能です。 =SUMPRODUCT(A1:A4,B1:B4)

参考URL:
http://www2.odn.ne.jp/excel/waza/function.html

関連するQ&A