• 締切済み

再質問 長いIF文を短くしたい

お世話になっております 先日1/24に、条件を示さずに「長いIF文を短くしたい」という質問をしてしまいました こちらの手抜きをお詫びします 前回keithinさんにアドバイスいただいた方法で書き直しましたので これをさらに簡単に書く方法があれば教えてください 以下は、Private Sub Worksheet_Change(ByVal Target As Range)内のマクロです If Target.Row >= 15 And Target.Row <= 100 And Target.Column = 9 Then If Range("I" & Target.Row).Value < Range("J" & Target.Row).Value Then If Range("G" & Target.Row).Value >= 1 Then If Range("I" & Target.Row).Value >= Range("G" & Target.Row).Value Then If Range("I" & Target.Row).Value Mod Range("G" & Target.Row).Value = 0 Then  処理 End If End If End If End If End If

  • maamaa
  • お礼率85% (274/322)

みんなの回答

回答No.2

こんにちは。 前回の質問内容「長いIF文を短くしたい」を、改めてよみました。 この場合は、回答者への気遣いはそれほどないようですね。ご質問に出ているコードですと、ご質問者さん以外のコードでは、ちょっと手控えたくはなりますが。 これ自体は、コーディング・スタイルの問題だと思いますが、正解があるわけではなく、エラーがでなければ、それで良いとするしかありません。あまりスタイルにこだわると、本末転倒になりかねません。むろん、私の以下のコードは、スタイルにこだわったものであり、書き換えの際にミスをしやすいのはやむを得ません。 >IF 条件1 and 条件2 and 条件3 and 条件4 and 条件5 Then 実際、このような時、and をつないでいくことは多くありませんが、かと言って、If構文で、あまり深いネストにしないのが慣例です。ただ、まとめられる条件は、まとめるほうがよいと思います。 イベント・ドリブン型マクロは、少し特殊で、除外するものを先にし、マクロのコードを中まで、くぐらせないようにします。コードを良く読むと、If構文すべては、除外項目が並んでいるだけのようですから、If構文のネストは必要はありません。 変数でまとめるというのも一案ですが、以下のような方法もあります。 '// Private Sub Worksheet_Change(ByVal Target As Range)  Dim n  Dim i As Long  n = Target.Value  i = Target.Row  If Intersect(Target, Range("I15:I100")) Is Nothing Then Exit Sub '入力セルが、範囲にない場合  If Range("G" & i).Value <= 1 Then Exit Sub  If n >= Range("J" & i).Value Or n < Range("G" & i).Value Then Exit Sub  If n Mod Range("G" & i).Value <> 0 Then Exit Sub   '処理   Stop  '←End If は要らない。 End Sub '//

  • mshr1962
  • ベストアンサー率39% (7418/18948)
回答No.1

何度も出てくるRangeの列がI,J,Gのみなのだから変数を使えばいいのでは? Private Sub Worksheet_Change(ByVal Target As Range) TR = Target.Row TC = Target.Column IR = Range("I" & TR).Value JR = Range("J" & TR).Value GR = Range("G" & TR).Value If TR>= 15 And TR <= 100 And TC = 9 Then If IR < JR Then If GR >= 1 Then If IR >= GR Then If IR Mod GR = 0 Then  処理 End If End If End If End If End If

maamaa
質問者

お礼

ありがとうございます まさか、こんな変数の使い方があったとは・・・ 勉強になりました

関連するQ&A

  • VBAエラー「スタック領域が不足しています」

    C2とD2のセルに英文字を入力した時,先頭文字を大文字にするVBAを組んだのですが,いざ実行すると「スタック領域が不足しています」と出てしまいます。以下にコードを示します。 'Sheet1 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range)   If Target.Row = 2 And Target.Column = 3 Then     Range("C2").Value = StrConv(Range("C2").Value, vbProperCase)   End If   If Target.Row = 2 And Target.Column = 4 Then     Range("D2").Value = StrConv(Range("D2").Value, vbProperCase)   End If End Sub なぜこのようなエラーが出るのでしょうか。考えれば考えるほど合っているように思えて仕方なくなったので,ミスがあればご指摘をおねがいします。

  • 2つのVBAを組み合わせる方法

    お世話になります、2つのVBAを組み合わせる方法で迷っています。 1つ目が Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, k As Long, myNum As Long If Intersect(Target, Range("C1,B9:B39")) Is Nothing Or Target.Count > 1 Then Exit Sub Application.EnableEvents = False With Target If .Column = 3 Then myNum = WorksheetFunction.Max(Range("B9:B39")) If IsDate(.Value) Then For i = 9 To 39 If Cells(i, "A").Value = "" Then Cells(i, "B").Value = "" Else Cells(i, "B") = myNum + i - 8 End If Next i End If Else i = .Row If .Value = "" Then Range(Cells(i + 1, "B"), Cells(39, "B")).ClearContents Else For k = i + 1 To 39 If Cells(k, "A").Value = "" Then Cells(k, "B").Value = "" Else Cells(k, "B") = Cells(k - 1, "B") + 1 End If Next k End If End If End With Application.EnableEvents = True End Sub です。 2つめが Private Sub Worksheet_Change(ByVal Target As Range)  Application.EnableEvents = True If Intersect(Target, Range("R8:R38")) Is Nothing Then Exit Sub Application.EnableEvents = False Range(Cells(Target.Row, 18), Cells(39, 18)).Value = Target.Value Application.EnableEvents = True End Sub です。2つのPrivate Sub Worksheet_Change(ByVal Target As Range)イベントのVBAですが、どのようにして組み合わせれば良いのでしょうか?

  • エクセル VBAマクロ if文 はどうすれば?

    先ほど質問したのですが、さらにわからなくなったのでお願いします 先ほどの質問 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ http://okwave.jp/qa/q7236338.html >変数と式の両立は難しいでしょうからどうすればよいのでしょう?  ⇒関数では出来無いのはエクセルの常識ですのでマクロ(VBA)組込みになります。 一例です。 対象シートタブ上で右クリック→コードの表示→以下のコード貼り付けてA1に枚数を入力して お試しください。 サンプルコード Private Sub Worksheet_Change(ByVal Target As Range) 単価 = 5 If Intersect(Target, Range("A1")) Is Nothing Then Exit Sub If IsNumeric(Target.Value) And Target.Value > 0 Then  Application.EnableEvents = False  Target.Value = Target.Value * 単価  Application.EnableEvents = True End If End Sub ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ↓変更&応用したのですが、、、、 EX:(セル)    セル番号  用紙種類1~3       用紙種類    C12   A3モノクロ1     D12  A3カラー1    C13   A3モノクロ2     D13  A3カラー2    C14   A3モノクロ3     D14  A3カラー3 ※金額の違いは、モノクロとカラーの値段が違うだけ  1~3は金額的な違いはない とあった場合、 ためしに先ほどのを応用して用いたのですが 変更点は、用紙サイズ、カラーの有無による金額        出力先セルの番号 Private Sub Worksheet_Change(ByVal Target As Range) を Private Sub A4_mono_1(ByVal Target As Range) Private Sub A4_mono_2(ByVal Target As Range) ・             ・            ・ と変更したのですがうまく動作しなかったのですが、 どういった点が悪かったのでしょうか? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 最終的な質問↓ 上記のものはVBAマクロ文は基本1つのみなので、if文で作らなくてはいけないということが分かったのですが、そこでさらに疑問が浮かびました、 Private Sub Worksheet_Change(ByVal Target As Range) If or(target.columns = C12:C14) Then 単価1 = 7.6 If Intersect(Target, Range("C12:C14")) Is Nothing Then Exit Sub If IsNumeric(Target.Value) And Target.Value > 0 Then Application.EnableEvents = False Target.Value = Target.Value * 単価1 Application.EnableEvents = True単価1 = 7.6 elseif or(target.columns = D12:D14) Then 単価2 = 30.6 If Intersect(Target, Range("D12:D14")) Is Nothing Then Exit Sub If IsNumeric(Target.Value) And Target.Value > 0 Then Application.EnableEvents = False Target.Value = Target.Value * 単価2 Application.EnableEvents = True End If End Sub としたっ場合全く式になっていません どのようにすればよいのでしょう?

  • セルの値をファイル名にするには

    現在下記のマクロを入力しています。 Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$C$10" Then Target.Offset(-6, 2).Value = Date End If End Sub この時 ファイル名を SHEET1のA1 セルの値を利用してファイル名にするために下記の内容を入れてブックを保存したいと考えています。 上記のマクロが入っていないときは上手く行くのですが下記を追加するにはどうすればいいかご指導いただけませんでしょうか。 宜しく御願いします。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row = 1 And Target.Column = 1 Then ActiveSheet.Name = Target.Value ThisWorkbook.SaveAs ThisWorkbook.Path & "\" & Target.Value End If End Sub

  • エクセルコードについて

    エクセルコードについて Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)   If Target.Row >= 1 And Target.Row <= 10 And Target.Column >= 1 And Target.Column <= 10 Then     If Target.Value = "○" Then       Target.Value = ""     Else       Target.Value = "○"     End If     Cancel = True   End If End Sub ではセルA1~J10ですが、これをA1~A10などに変更するのにはどのようにすればよろしいでしょうか。

  • 「Worksheet_Change」で2つの操作を

    お世話になります。 当方、エクセルの超初心者です。 仕事で、ある作業表の作成を任されたのですが、一部が思い通りに動作しません。 最初は「例1」のような記述によりエラーしました。 【例1】 Private Sub Worksheet_Change(ByVal Target As Range) (内容1) End Sub Private Sub Worksheet_Change(ByVal Target As Range) (内容2) End Sub その後、過去の回答にあった類似案件を参考に「例2」のように書き換えましたが、 実行されるのは1つ目のみで、2つ目の内容は無視され、困っております。 【例2】 Private Sub Worksheet_Change(ByVal Target As Range) (内容1) (内容2) End Sub ちなみに実データは以下の通りです。 Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Count <> 1 Then Exit Sub If Intersect(Target, Range("k6:k55")) Is Nothing Then Exit Sub If Target.Value = "" Then Target.Value = "○" Else Target.Value = "" If Target.Count <> 1 Then Exit Sub If Target.Column <> 2 Then Exit Sub If Target.Row < 6 Or Target.Row > 45 Then Exit Sub Call ShowCalendarFromRange2(Target) End If End Sub 見様見真似で作ったため、恥ずかしながら基本が全く理解できていません。 恐らく簡単なミスだと思うのですが、自力では解決方法を探し出せませんでした。 何とか2つの内容が実行できないものでしょうか。 どうか、お知恵をお貸し下さい。

  • WorkSheet_Changeを2つ反映させる

     下記のコードをWorkSheetで2つ反映させるにはどうしたらいいでしょうか?どちらか一つなら反映するのはわかりますが、どう名前を変更すればいいのかお教え願えませんでしょうか? windows7・SP1 Office2010 Private Sub WorkSheet_Change(ByVal Target As Range) If Intersect(Target, Range("C1")) Is Nothing Then Exit Sub '検査範囲 Application.EnableEvents = False '再帰実行の停止 If Range("C1").Value <> Sheets("祝祭日").Range("A1").Value Then MsgBox ("祝日の設定を反映するため年度を同じにしてください。") End If Application.EnableEvents = True End Sub Private Sub WorkSheet_Change(ByVal Target As Range) Dim MyRow As Long Dim MyCol As Integer MyRow = Target.Row MyCol = Target.Column With Worksheets("メイン・1").Select If MyRow = 1 And MyCol = 7 Then If Target = 4 Then 'または If Target = 1 Then メインデータの復元 '動かしたいマクロ名 End If End If End With End Sub

  • (少数点、第三位から切り捨て)をこのマクロにどう入力すればいいですか??

    四捨五入を切捨て(第三位)するにはどうしたらいいのでしょうか?? VBAをちゃんと理解できていないので、誰か分かる人助けてください!! ついでにROUNDDOWNとかの関数はVBAに入力するコードとしては、 まったく別物なんでしょうか??初心者が生意気言ってすいません・・・。 Private Sub Worksheet_Change(ByVal Target As Range) On Error Resume Next Application.EnableEvents = False If Range(Target.Address).Column = 2 And _ Range(Target.Address).Row >= 5 And _ Range(Target.Address).Row <= 10 Then Range(Target.Address).Value = _ Range(Target.Address).Value / 19 End If Application.EnableEvents = True End Sub よろしくおねがいします・・。 カテゴリー間違えて入れなおしました。すみません・・。

  • (少数点、第三位で切り捨て)をしたいんですが、このマクロに何を足せばいいですか??

    四捨五入を切捨て(第三位)するにはどうしたらいいのでしょうか?? VBAをちゃんと理解できていないので、誰か分かる人助けてください!! ついでにROUNDDOWNとかの関数はVBAに入力するコードとしては、 まったく別物なんでしょうか??初心者が生意気言ってすいません・・・。 Private Sub Worksheet_Change(ByVal Target As Range) On Error Resume Next Application.EnableEvents = False If Range(Target.Address).Column = 2 And _ Range(Target.Address).Row >= 5 And _ Range(Target.Address).Row <= 10 Then Range(Target.Address).Value = _ Range(Target.Address).Value / 19 End If Application.EnableEvents = True End Sub よろしくおねがいします。

  • シート内の特定のセルの範囲が変化した時、

    シート内の特定のセルの範囲が変化した時、 まずA列の最大値を求めて、その後A列とD列のそれぞれの条件にあった行のA列に 最大値+1を表示させるようにしたいのですが動作しません。 なぜ動かないか教えて下さい。 参考までに、そのプログラムを記載します。 宜しくお願いします。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row <= 3 Or Target.Row > 65000 And Target.Column = 4 Then Dim i, j, max As Integer max = 0 For i = 3 To Cells(Rows.Count, 1).End(xlUp).Row If max < Range("A" & i).Value Then max = Range("A" & i).Value End If Next i For j = 3 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(j, 1) = "" And Not Cells(j, 4) = "" Then Cells(j, 1) = max + 1 End If Next j End If End Sub

専門家に質問してみよう