• ベストアンサー

ExcelVBAの変数を使うコツ

matyuといいます。よろしくお願い致します。 基本的な部分の質問です。 VBAでプログラムを考える際に変数を使うタイミングは非常に多いと思いますが、 どういうタイミングでどういう部分を変数として扱えばいいか分からなくて困っています。 添付したファイルのような問題があったとします。 この問題では、日給の部分を"kyuyo"として宣言していますが、 私が考えると曜日も平日と休日で変化するし、時給も1000円と1200円、勤務時間も何が入るか分からないな・・・となってしまい、いくつもいくつも変数にしようとして結果答えと違ってしまいます。 どこに着目して必要最小限の変数宣言ですっきりしたプロシージャーを書くようにしたらよいのでしょうか? 私が考えるに、最終的に導きだされなくてはならないのは"日給(kyuyo)"だからという考え方でいいのでしょうか 【問題】 セル【C16】に曜日として「平日」「休日」を、【D16】に勤務時間を入力してプロシージャを実行すると、日給をセル【E16】に表示する「練習1」プロシージャを作成しましょう。 また、勤務時間が空欄の場合はセル【E16】に「休み」と表示されるようにします。 【この問題の回答】 Sub 練習1() Dim kyuyo As Currency If Range("D16").Value = "" Then Range("E16").Value = "休み" Else If Range("C16").Value = "平日" Then kyuyo = 1000 * Range("D16").Value Range("E16").Value = kyuyo ElseIf Range("C16").Value = "休日" Then kyuyo = 1200 * Range("D16").Value Range("E16").Value = kyuyo End If End If End Sub

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

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

こんにちは。 >【この問題の回答】 >どこに着目して必要最小限の変数宣言ですっきりしたプロシージャーを書くようにしたらよいのでしょうか? 練習問題で、そのような必要はないと思います。だいたい、そのようなコード自体は練習用としてか存在しませんし、VBAとしては成立しているとはいえません。そういうことを考えていると、上達しません。 あえて書くなら、以下のようなことだと思います。時間を、整数で入れないなら、ある意味では、Currency 型は必要かもしれませんが、Currency型がなぜ必要かなんていうのを、このレベルのコードで持ち出すことは、私は、あまり関心しません。 Private Sub CommandButton1_Click()   If Range("D16").Value = "" Then     Range("E16").Value = "休日"     Exit Sub   End If      If Range("C16").Value = "平日" Then     Range("E16").Value = 1000 * Range("D16").Value   ElseIf Range("C16").Value = "休日" Then     Range("E16").Value = 1200 * Range("D16").Value   End If End Sub 通常は、1000円,1200円は、定数(Const)を置いたりしますが、初心者の方は、名前--登録を使って行うことが多いようです。ただ、後者はトラブルが想定されますのでお勧めいたしません。 p.s. 「FOM出版よくわかるExcel2003マクロ/VBA」 私自身、FOMで最初にVBAを覚えようとしましたが、導入部分から、混乱させるようなものが多く、実際に、今の私から見ると、そのようなコードはありえないという内容があります。入門レベルで癖というか懲りすぎているのです。この著者は、VBAをあまり詳しくないのではないかなって思うことがあります。教える側は、我慢しなければならないわけで、自分がいつも書いているコードをそのまま提示してはいけないのです。 ですから、このテキストはお勧めしません。ここのカテゴリでいくつかお勧めの本が出ているはずですから、それを参考にしてもよいと思います。ただ、いずれにしても、入門レベルであれこれ複線を考えることは、上達にはマイナスになります。 VBAは、短いフレーズをいくつも覚えることです。 なお、入門レベルで、こういう書き方はありえないです。 >Else >If Range("C16").Value = "平日" Then

matyu0531
質問者

お礼

Wendy02様 回答ありがとうございます。 >入門レベルであれこれ複線を考えることは、上達にはマイナスになります。 >VBAは、短いフレーズをいくつも覚えることです。 上記の件大変に参考になりました。 また、Wendy02さんに書いていただきました記述も初心者が見てもわかりやすいです。 私はこのシリーズを1度に2冊買ってしまい、少々期待しすぎていました。(一応、以前通っていたナガセPCスクールで使っていたテキストがFOMだったのと、amazonのレビューを見て買ったんですが・・・) テキストは良いものを選ばないといけないことを実感しました。 こちらのカテゴリで皆さんが使われている書籍を探してみます。

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

その他の回答 (4)

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

#2の回答者です。 私も 「かんたんプログラミングExcelVBA」 は、お勧めです。大村あつしさんというのは、Moug の主催者です。 やっと、Office 2007 のシリーズ3冊がそろったようですね。ずいぶん時間が掛かりました。このシリーズは、ともかく、内容的に細かいです。同じ出版社から出ているVisual Basic 版と比較すると、倍以上に綿密に書かれていますから、一度ぐらいでは覚えませんね。(値段的にちょっと高いなって思いますが、学校などに教わりに行くと、数万円から十数万円も取られてしまいます。スクールを探しましたが、予算が合いませんでした。)ペースとしては、1ヶ月1冊で、だいたい、3ヶ月で一通り終えるようにします。分からないところは、飛ばしてもよいので、本の章のタイトルぐらいは覚えるようにします。私は、UserForm がすぐに覚えられませんでしたので、後回しにしてしまいました。 Excel VBAの難しさというのは、実は、Excelのワークシートを見ていかなくてはならないということです。VBのプログラマが良く間違えるのは、ワークシートをきちんと認識してコードが書けないからです。Excel独特のVBAコードが存在するのですが、そうではないと思っている人たちも多いようです。逆に、Excel VBA で、VBAは全て通用すると思う人もいるようです。 それと、繰り返しますが、練習問題は、単にこなしていくことにしたほうがよいです。あるレベルになるまでは、結局のところ理解できないことが多いし、応用も利きません。大村さんの著書ですと、応用編の「動的配列」まで達しないと、あまり大したことができないと思ったほうがよいです。それと、VBAのワークシート関数を使うのは、後に回したほうがよいです。1年以上も理解できないものもあります。 明示的に Currency 型変数を使うのは、浮動小数点丸め誤差を防ぐ目的です。それは、\1.000というように、セル上の 「\ マーク付きの値」を、VBAで取り扱うと、Currency 型になります。しかし、練習用で整数を扱うなら、Long 型で十分です。

全文を見る
すると、全ての回答が全文表示されます。
  • rukuku
  • ベストアンサー率42% (401/933)
回答No.4

はじめまして この練習問題の場合、以下のようにすると、変数を一度も使わずにできます。 >私が考えると曜日も平日と休日で変化するし… セルの値も「変数」です。Rangeを使ってセルを参照すればいい場合には、変数に格納する必要はありません。 この問題の応用として17行目以降にもデータが入っていてそれをすべて自動的に計算しようとすると(平日・休日の区分は省略)、 Range("C10").Value が何度も出てきます。このときに Jikyu = Range("C10").Value としておけば、プログラムが少し短くなりますし、分かりやすくなります。 ------------------------------- Sub 練習1() Range("E16").Value = "エラー!" If Range("C16").Value = "平日" Then Range("E16").Value = Range("C10").Value * Range("D16").Value If Range("C16").Value = "休日" Then Range("E16").Value = Range("C11").Value * Range("D16").Value If Range("D16").Value = "" Then Range("E16").Value = "休み" End Sub

matyu0531
質問者

お礼

rukuku様 回答ありがとうございます。 いろいろな記述の仕方があるんですね~ 私の場合まだまだ勉強が足りないため、まだ問題を読んですぐに "型"が頭に浮かぶところまでいっていないようです。 色々なバリエーションの問題をこなす必要がありますね

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

この問に関する直接の回答ではありませんが FOMのExcelやAccessのテキストは分かりやすいと非常に好評でした。 僕も それで教わりました。 FOMのVBAの方に関しては見ていないので何とも言えませんが 僕は「かんたんプログラミングExcelVBA」を全シリーズ買ってしまいました。(通称「かんプロ」) (とりあえず“アマゾン”で3冊全てがトップ10入りしているという事だったので) これが分かりやすいかどうかは まだ分かりません。 例題は あり得ないような例題だったりしていますが、でも非常に丁寧親切に記載されているような気はします。 著者は「大村あつし」という人です。 ある程度 理解されてる方なら「基礎編」は必要ないでしょうから 他の「コントロール・関数編」と「応用編」を購入されてはいかがでしょうか。 (僕もマクロぐらいは知ってましたが基礎編を読んで改めて学んだこともありましたけど) ちなみに変数は3つも4つも あってもOKっぽい気がします。 何かの参考にでもなれば幸いです。

matyu0531
質問者

お礼

ookami1969様 回答ありがとうございます。 そうです!まさにその本を買おうか迷ってFOMの方が実務で使える例題が豊富という謳い文句で(というより、メールでサポートを受けられる的な記述がamazonのレビューあったのもで・・・)買ったのですが、Wendy02様のご意見の通り、少々期待はずれだったような気が進めていいけばいくほど強くなってきました。 手をつけていないFOMの2冊目の実践編をレシートがあるので返品してw、大村あつしさんの書籍と交換してもらおうかと考え中です。 レビューでは非常に評価が高いことは知っていたんですが。。。ん~ 話は変わりますが、やっぱりアクセスもできたほうがいいですよね アクセスはまったく触ったことがない超ど素人なもんで><

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

状況にもよるが、基本的に、主に何に使われているかでokでしょ 私だったら'nikkyu'にするかなあ 'kyuyo'でも通じるけどね それから1000, 1200とじかに数値を書くのではなく セルから取り出した方がいいと思うけど Range("C10").Value

matyu0531
質問者

お礼

phoenix343さん回答ありがとうございます。 私がこのテキスト(FOM出版よくわかるExcel2003マクロ/VBA)をやって感じたことは、 答えって、表現の違いで何通りも存在するんだ。。というところで、 例えば、時給の部分もたまたま2つしかないのでそのまま数字を 使ってますが、じゃぁもっと多かったら変数にするのか? とか、柔軟に対応できる記述なのか?という疑問をもってしまうんです。 ご指摘のとおり時給を"1000"という数値で記述するのではなく、 セルの値?として記述しないと時給が変更されたら記述を全て 書き換えないといけなくなりますよね? ケチをつけるわけではないですが、この入門書は問題と回答(一行一行の意味)が書いてあるだけで、 "どうしてその記述にしてるのか"という部分の解説が非常に少ないと感じました。 (はじめに使った解説書"excelVBAのプログラミングの コツとツボがゼッタイにわかる本"が非常によかったので)

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

関連するQ&A

  • ExcelVBA 変数について

    ExcelでD列が500以上のデータの合計をセルD21に表示するプロシージャを作成する場合、 Sub Test3_4_2() Dim i, total '合計用変数total For i = 2 To 19 If Cells(i, 4) >= 500 Then total = total + Cells(i, 4) End If Next Range("D21") = total End Sub 上記の変数Totalの使い方で、total=total+cells(i,4)の部分の意味が 分かりません。 お分かりになられる方がいらっしゃいましたら、ご教示願います。

  • VBAでの計算後のセルに2重線で囲む

    まだPC・VBA不慣れな為、実行できないので、教えてください。 c16セルに休日を入力すると無理つぶしは成功しましたが、c16セルに祭日を入力すると赤の2重線で囲みたいのですが、できませんので、方法をお願いします。 もう1点がCELLS・RANGEを使った2種類の方法をお願いします。 よろしくお願いします。 Sub 練習44() Dim kyuyo As Currency If Range("c16").Value = "祭日" Then Worksheets("練習1If~Then").Cells(16, 3).xlDouble.ColorIndex = 3 ElseIf Range("c16").Value = "休日" Then Worksheets("練習1If~Then").Cells(16, 3).Interior.ColorIndex = 5 Else Worksheets("練習1If~Then").Cells(16, 3).Interior.ColorIndex = 10 End If End Sub

  • VBAで処理フラグの立て方

    こういった条件でやりたいのですがうまくいきません・・・ 処理フラグの立て方は間違っていないと思うのですが・・・ ちょっとセルとかは変えてあります。 もしE3の値が4で割り切れたら8行目を削除し次の処理は行わない もしE3の値が4で割り切れなかったらE4の値が4で割り切れるか処理をする。 割り切れたら18行目を削除 E3とE4の値両方が4で割り切れなかったら8行目を削除し1行あがるので17行目を削除したいです Sub rdlt() If Range("I1").Value = 0 Then Range("I1").Value = 1 '処理は一度きり If Range("E3").Value Mod 4 = 0 Then Rows("8:8").delete '4で割れたとき8行目を削除 Range("J1").Value = 1 '4で割れたときは次の処理用にフラグ End If If Range("J1").Value = 0 Then 'E3が4で割れなかったときは処理する If Range("E4").Value Mod 4 <> 0 Then Rows("18:18").delete Range("J1").Value = 1 End If End If End If End Sub

  • ExcelVBA 二つのセルに入力された時の判定

    セルA1とA2両方に値が入力された時、セルA3に文字を入力するマクロを作りたいです。 下記プログラムで試しているのですが、ステップインで見ると最初のIFでTrue判定されてしまいます。 どうすればこの条件を満たすマクロになるのか、教えて頂けないでしょうか。 以上、宜しくお願い致します。 Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("A1")) Is Nothing Or Intersect(Target, Range("A2")) Is Nothing Then Exit Sub Else If Range("A1").Value <> "" And Range("A2").Value <> "" Then Range("A3").Value = "入力済み" End If End If End Sub

  • エクセルVBA の変数を使うべきでしょうか?

    はじめまして。エクセル初心者です。 書籍やサイトで勉強させてもらっていますが、VBAがなかなか難しくてすぐに壁にぶつかってしまいます。少々困ってしまい、詳しい方のアドバイスを頂ければと質問を投稿させていただきました。 どうか宜しくお願い致します。質問ですが、 以下のようなコードで、sheet5のB列の任意のセルをダブルクリックした場合、sheet5のBCD列の同じ行のセル値がsheet1の指定した列に入力されるという処理を作りました。 これで一応目的の動作はするのですが、数が増えると「コンパイルエラー・プロシージャが大きすぎます」というメッセージがでてしまいます。列や行には規則性があるので、もしかしたら変数というものを使ってコードを書き直せばいいのかなと思いネットで調べてみたのですが、今のところさっぱり理解できません。 申し訳ありませんが、分かりやすくご教授いただけないでしょうか。バージョンは2003を使っています。 また、下のコードですと、sheet5のBCDいずれかのセルに空白があった場合、sheet1の列に入力されるときに入力される行がずれてしまいます。今は空白を何かで埋めて対処しているのですが、この問題の解決策も教えて頂けると助かります。どうか宜しくお願い致します。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, cancel As Boolean) If Target.Address = "$B$2" Then Worksheets("sheet1").Range("B" & Rows.Count).End(xlUp).Offset(1).Value = Target.Value Worksheets("sheet1").Range("H" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("B2") Worksheets("sheet1").Range("K" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("C2") Worksheets("sheet1").Range("M" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("D2") Worksheets("sheet1").Activate cancel = True End If If Target.Address = "$B$3" Then Worksheets("sheet1").Range("B" & Rows.Count).End(xlUp).Offset(1).Value = Target.Value Worksheets("sheet1").Range("H" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("B3") Worksheets("sheet1").Range("K" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("C3") Worksheets("sheet1").Range("M" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("D3") Worksheets("sheet1").Activate cancel = True End If If Target.Address = "$B$4" Then Worksheets("sheet1").Range("B" & Rows.Count).End(xlUp).Offset(1).Value = Target.Value Worksheets("sheet1").Range("H" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("B4") Worksheets("sheet1").Range("K" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("C4") Worksheets("sheet1").Range("M" & Rows.Count).End(xlUp).Offset(1).Value = Worksheets("sheet5").Range("D4") Worksheets("sheet1").Activate cancel = True End If   ・     ・   ・     ・   ・     ・ End Sub

  • 変数宣言の不思議

    いつも教えてgooの皆さんに大変お世話になっております 以下は、Private Sub Worksheet_Change(ByVal Target As Range)内の 文字列操作のマクロですが、MiniLenを変数宣言しなくても マクロは狙った通りの動きをします なぜでしょうか? どなたか教えてください Dim MojiLen as String 'MojiLen(文字数という意味で) MiniLen=3 '最少文字数 If Not IsNumeric(Right(Range("E16").Value, 1)) Then 'E16の右端が数値でないなら MojiLen = "8" ElseIf CInt(Right(Range("E16").Value, 1)) < MiniLen Then MojiLen = MiniLen Else MojiLen = Right(Range("E16").Value, 1) 'E16は固定です End If Range("E" & Target.Row).FormulaR1C1 = "=LEFT(RC[-1]," & MojiLen & ")"

  • 【ExcelVBA】IF条件を満たしているのに、IF条件のところで止まってしまう

    Sub test1() 変数1 = IsEmpty(Range("C1")) If Range("A1") > 0 And Range("B1") = 0 And 変数1 = True Then   test2 End If End Sub 止まったときのデバッグでの表示は Range("A1")は「100」(セルの中身) Range("B1")は「0」(セルの中身) 変数1はRange("C1")がエラー表示なので「True」 すべての条件を満たしているのですが、 IF条件のところで止まってしまいます。 (IF条件のところの1行が黄色くハイライトになっている状態) 止まったデバッグの後に、F5を押して実行させると、 IF条件の続きから実行されて、test2が実行されて処理が終了します。 何で、IF文のところで一度止まってしまうのかわかりません。

  • エクセルのVBAで条件付でフォントを変更したいのですが

    たとえばD19のセルには他のセルに入力された文字数が表示されるようLEN(C19)といったような関数が入力されています。D19の値が20より大きければE19のフォントは20にそれ以外なら11にしたいとします。 ちなみにE19も関数が入力さています。 下記でよいのかなと思ったのですが・・・ 直接数値を入力する場合はちゃんと動くのですがD19が数式になるとうまく行きません。どなたか教えてください。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$D$19" Then If Target.Value > 20 Then Range("E19").Font.Size = 20 Else Range("E19").Font.Size = 11 End If End If End Sub

  • ExcelVBAで直ぐに繁栄しないPrivate

    ExcelVBAで直ぐに繁栄しないPrivate Sub Worksheet_Change(ByVal Target As Range) If Target = Range("A1") Then   Range("B1").Value=fncMojiHenkan(Range("A1").Value End If End Sub セルA1に文字列を入力したり、他から文字列をコピペしてEnterキーを押しても、セルB1に直ぐに繁栄されません。 もう一度Enterキーを押すか矢印キーでセル移動しないとセットした値がB1に表示されません。 値をセットして直ぐに表示させるにはどうしたらいいでしょうか?

  • マクロで分岐をさせる方法

    下記の記録マクロでWith→End With 間にIFで分岐を試みたのですが エラーになります。どうすれば出来るのか伝授をお願いします。 マクロは初心者です。 Dim hensuh(2) As Integer Dim dekiru As Long Dim kinek As Long Dim uineu As Long Dim myTime As Date Dim flg As Boolean Sub OnTimeSamp1() Application.OnTime EarliestTime:=TimeValue("09:00:00"), Procedure:="Ontime_Set" '記録開始 Application.OnTime EarliestTime:=TimeValue("11:00:00"), Procedure:="Ontime_Reset" '記録終了 End Sub Sub Ontime_Set() 'トグルになっている If flg = False Then flg = True myTime = Now + TimeSerial(0, 0, 1) ElseIf flg = True Then flg = False Else Exit Sub End If If Range("A1").Value = "" Then Range("A1").Value = Format(Now, "hh:mm:ss") '時間記録(スタート) End If Application.OnTime EarliestTime:=myTime, _ Procedure:="my_Procedure", Schedule:=flg If flg = False Then myTime = 0 End If End Sub Sub my_Procedure() Worksheets("kirokuyou").Activate 'ワークシートをアクティブにする。(記録中別のワークシートを開けた場合そこに記録されてしまうのを防ぐ) With Range("A65536").End(xlUp).Offset(1) .Value = Format(Now, "yyyy:mm:dd:hh:mm:ss") '時間記録 .Offset(, 1).Value = Range("S3").Value 'S3 の値 .Offset(, 2).Value = Range("T3").Value 'T3 の値 .Offset(, 3).Value = Range("U3").Value 'U3 の値 .Offset(, 4).Value = Range("V3").Value 'V3 の値 dekiru = Range("V3").Value Range("V6").Value = dekiru kinek = Range("T22").Value Range("T18").Value = kinek uineu = Range("U22").Value Range("U18").Value = uineu 'IF S17 >= 120 Then 'hensuh(0) = Range("S17").Value ←変数に代入後、分岐させたいのですがエラーになる 'Elseif S17 >= 110 Then 'hensuh(1) = Range("S17").Value ←変数に代入後、分岐させたいのですがエラーになる 'Elseif S17 >= 100 Then 'hensuh(2) = Range("S17").Value ←変数に代入後、分岐させたいのですがエラーになる 'End If flg = False myTime = 0 End With Call Ontime_Set End Sub Sub Ontime_Reset() 'タイマーリセット On Error Resume Next Application.OnTime EarliestTime:=myTime, _ Procedure:="my_Procedure", Schedule:=False If Err.Number > 0 Then MsgBox "OnTime設定はされていません。", 64 Err.Clear flg = False Else MsgBox myTime & "の設定は解除されました。", 64 flg = False myTime = Empty End If End Sub

このQ&Aのポイント
  • 常陽銀行のサービス・手続きについて質問です。払い出し金額は100円単位で下ろすことができるのでしょうか?
  • 常陽銀行では、払い出し金額は100円単位まで下ろすことができますか?サービス・手続きについて教えてください。
  • 払い出し金額についてお伺いします。常陽銀行のサービス・手続きでは、100円単位での下ろし方が可能でしょうか?
回答を見る

専門家に質問してみよう