仕事を頑張る人のおしりトラブル対策

こんにちは。
if文についておしえてください。
以下のようなマクロがあるとします。

変数 tensuuに-1をいれて実行すると①→②のように動作し「入力エラー」と表示されます。
tensuuに120を入れて実行すると①´→②´の順に動作し「入力エラー1」と表示されます。

どして、-1のときは入力エラー1にはいかず入力エラーにいくのでしょうか?
120のときは入力エラーにはいかず入力エラー1にいくのでしょうか?

動きがよくわかりません。
IF文とELSEはどういう紐づけがされているのでしょうか?

よろしくおねがいいたします。
   
Sub t()
tensuu = -1
If tensuu >= 0 Then '①
If tensuu <= 100 Then '①´
If tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If
Else
MsgBox "入力エラー1" '②´
End If
Else
MsgBox "入力エラー" '②
End If
End Sub

このQ&Aに関連する最新のQ&A

A 回答 (4件)

If 〜 Then 〜 Else 〜 End If


で1セットです。

ネスト(入れ子)になったIF文というのは、 Then 〜 とか Else 〜 の〜の部分にIf文がくるものです。
ですから、外のIfを越えてしまうことはありません。
よって、一番内側から見ていけば、構造がはっきりします。


一番内側から見ます。

If tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If

が1セットです。
これを 「文1」とすると元のプログラムは

If tensuu >= 0 Then '①
If tensuu <= 100 Then '①´
「文1」
Else
MsgBox "入力エラー1" '②´
End If
Else
MsgBox "入力エラー" '②
End If

となります。この状態で「一番内側」を見ると

If tensuu <= 100 Then '①´
「文1」
Else
MsgBox "入力エラー1" '②´
End If
です。これを「文2」とすると

If tensuu >= 0 Then '①
「文2」
Else
MsgBox "入力エラー" '②
End If


余談ですが
この例の場合、外側2つは、判定内容と処理とが離れてしまい、見辛いのは確かです。
if 条件 Then A Else B は if not条件 Then B Else A と同じ、ということから、Thenでの処理とElseでの処理を入れかえれば、
条件の直ぐ下の処理が来るので、見易さが格段によくなります。

If tensuu < 0 Then '① ' tensuu<0 は not (tensuu>=0)と同じ
MsgBox "入力エラー" '②
ElseIf tensuu > 100 Then '①´
MsgBox "入力エラー1" '②´
ElseIf tensuu >= 80 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If ' ElseIfで継いでいるので、ネストにはなっていない
    • good
    • 0
この回答へのお礼

ネストしているときの処理がよくわかりました。
ありがとうございました。

お礼日時:2017/02/24 14:51

「if文について」の直接の回答ではないので皆さん避けておられますが、


条件が「tensuu」1つの場合は、
Select Case 構文がお勧めです。
http://excelvba.pc-users.net/fol6/6_2.html

不等号が条件に入るのならば、「Is」も必要になります。
数値の範囲指定ならば 「to」も使用できます。

また、[Select Case True]をつかえば、もっと複雑な複数条件への対応も楽になると思います。

以上、今後のマクロ作成の参考にしてください。
    • good
    • 0

もしかしてですが、


If tensuu >= 0 Then '①
If tensuu <= 100 Then '①´
If tensuu >= 80 Then
この記述が勘違いを生みやすいのでは?

不等号は向きを揃える習慣をつけた方が判りやすいと思います。
If 0 =< tensuu Then '①
If tensuu <= 100 Then '①´
If 80 =< tensuu Then

最初の不成立を見落とされたのでは?
見当違いならごめんなさい。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
IF文のなかにIF文があるときの処理がわからなかったために
ご質問をさせていただきました。
ご回答ありがとうございました。

お礼日時:2017/02/24 14:45

プログラム入力の際にTABキーで段付け(インデント)をしていますか?


同じレベルのIf ~ Else ~ End Ifで同じ深さのインデントを付ける様にすれば流れが追いやすくなりますよ。

下のプログラムだと、tensuu = -1の場合、①の判定で対応するElse(②の上、インデントが同じ深さ)へとび、Elseの処理がされるのが分かりやすいと思います。

もちろんIf文だけなく、For~Next や Do While ~ Loopも同様です。

※下のプログラムについて
 この掲示板では半角のスペースは省略されてしまいますので敢えて全角スペースでインデントしています。

Sub t()
  tensuu = -1
  If tensuu >= 0 Then '①
    If tensuu <= 100 Then '①´
      If tensuu >= 80 Then
        MsgBox "合格"
      Else
        MsgBox "不合格"
      End If
    Else
      MsgBox "入力エラー1" '②´
    End If
  Else
    MsgBox "入力エラー" '②
  End If
End Sub
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
インデントはあまり意識しておりませんでした。
することによりって、かなりわかりやすくなりますね。
これをきに心がけてみようと思います。
ありがとうございました。

お礼日時:2017/02/24 14:49

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q[初心者です]VBAで指定列からAを検索し、発見したら隣のセルに値0を入れるマクロ。

VBAで指定列からAを検索し、発見したら隣のセルに0を入れるマクロを組みたいのですが、組み方がVBA初心者の為わかりません。
(例)
L列に、A、B、C、D、E、Fとランダムに文字が入っていて、
文字Aを検索し、発見したら隣のI列に値0を入れるというマクロです。

Sub Search()
Dim A As String
Set A = Worksheets("Sheet1").Cells.Find("A")
If A Is Nothing Then
ActiveCell.Offset(0, 1).Value = 0

End If
End Sub
と過去の質問で考えてみたのですが、Aがあった時、、、、
とコードが書けないです。
大変困っているので、ご教授頂けないでしょうか?
出来れば、そのままマクロに出来るコードを教えて頂けないでしょうか?
宜しくお願い致します。

Aベストアンサー

こんばんは。

#3さんのおっしゃっていることも、もっともなのですが、気になる点がありましたので、自分のことを踏まえて、書かせていただきます。

いずれ、また、同じようなケースが出会うと思います。こんな原則を考えてみたらどうでしょうか?それは、私も自身も同じなのですが、ワークシートのコマンドで行われるものは、記録マクロから作ってみるということです。他にも、「統合」とか、「置換」とか「オートフィルタ」「フィルタオプション」とかは、みんなパターンが決まっています。
その中の代表格が、この「Find」 です。

>Set A = Worksheets("Sheet1").Cells.Find("A")

>過去の質問で考えてみたのです

どうも、Find メソッドは、あるレベル以下の人は、省略する傾向があるようです。何が大事で、何が大事でないかというのは、やってみなければ分かりませんが、検索語だけを入れる書き方は、実務では、あまりしないほうがよいと思います。

だいたい、以下のTestFind2 ぐらいまでに、省略は、とどめたほうがよいです。

それは、Find は、必ずしも自分が思っているデフォルトとは違うことがあるので、「明示的(意図的に)」にオプションは入れたほうがよいです。
例えば、大文字小文字の違いを付けるなら、MatchCase:=True, 数式まで探すなら、LookIn:=xlFormulas

なお、Find メソッドは、5年経っても、たぶん完全に覚えられません。面倒なコードのひとつです。ですが、これはパターンが決まっているので、ひとつパターンが決まったら、それに当てはめればよいだけです。

#3さんで示されているMougのサンプルコードと似てはいるのですが、Mougのサンプルコードでは、Verionによって、失敗することがあります。

'--------------------------------------
'記録マクロをそのまま使う方法
Sub TestFind1()
Dim c As Range
 Set c = Columns("L:L").Find(What:="A", _
           After:=ActiveCell, _
           LookIn:=xlValues, _
           LookAt:=xlPart, _
           SearchOrder:=xlByRows, _
           SearchDirection:=xlNext, _
           MatchCase:=False, _
           MatchByte:=False, _
           SearchFormat:=False)
 c.Offset(0, 1).Value = 0
End Sub
'--------------------------------------
'TestFind1 をアレンジしてみる
Sub TestFind2()
Dim c As Range
'検索語
Const MYTXT As String = "A"
 Set c = ActiveSheet.Columns("L:L").Find(What:=MYTXT, _
           LookIn:=xlValues, _
           LookAt:=xlPart, _
           MatchCase:=False)
 If Not c Is Nothing Then
    c.Offset(0, 1).Value = 0
 End If
End Sub

'---------------------------------------
'複数ある場合(パターンを使った方法)
'---------------------------------------
Sub TestFind3()
  Dim c As Range
  Dim FirstAdd As String
  Const MYTXT As String = "A"
  Set c = ActiveSheet.Columns("L:L").Find( _
    What:=MYTXT, _
    LookIn:=xlValues, _
    LookAt:=xlPart, _
    MatchCase:=False)
  
  If Not c Is Nothing Then
    FirstAdd = c.Address
    Do
      c.Offset(, 1).Value = 0
      Set c = ActiveSheet.Columns("L:L").FindNext(c)
      If c.Address = FirstAdd Then Exit Sub
    Loop Until c Is Nothing
  End If
End Sub

こんばんは。

#3さんのおっしゃっていることも、もっともなのですが、気になる点がありましたので、自分のことを踏まえて、書かせていただきます。

いずれ、また、同じようなケースが出会うと思います。こんな原則を考えてみたらどうでしょうか?それは、私も自身も同じなのですが、ワークシートのコマンドで行われるものは、記録マクロから作ってみるということです。他にも、「統合」とか、「置換」とか「オートフィルタ」「フィルタオプション」とかは、みんなパターンが決まっています。
その中の代表...続きを読む

Q別のシートから値を取得するとき

Worksheets("シート名").Activate
上記のを行ってから別シートの値を取得するのですが、
この処理を行うと指定したシートへ強制的にとんでしまいます。。。

※イメージ
For ~ To ~
  Worksheets("シートA").Activate
  シートAの値取得
       :
  Worksheets("シートB").Activate
  シートBの値取得
Next

このイメージ処理を行うとものすごい勢いで画面がチカチカします。。。
シートを変えずに他のシートから値を取得する方法はないのでしょうか。
教えてください!

Aベストアンサー

Worksheets("シートA").Range("A1")

みたいな感じでできませんか?

QエクセルVBAのIf,Then 構文でOr条件とAnd条件の結合方法?

ワークシート関数で書けば
=IF(OR(F18=0,AND(F15>0,F16>0)),TRUE)です。
これをVBAで書こうとして

If Sheet1.Range("F18") = 0 Or Sheet1.Range("F15") > 0 And Sheet1.Range("F16") > 0 Then
MsgBox True
Else
MsgBox False
End If

とやってみたのですが、正しくないようです。
どのように書けばいいのでしょうか?

Aベストアンサー

>とやってみたのですが、正しくないようです。

式は正しいと思いますよ

ANDとORは、ANDが先に演算されます。/*と+-では、/*が先に演算されるようなものです。

でも、わかり易くするために、#1のかたのように括弧をつけるほうが良いですね。

Qユーザ定義型は定義されてません

こんばんは
実行すると「ユーザ定義型は定義されてません」と表示されます。
どなたかわかる方おしえてください。
Sub m()
Dim a As New NotesSession
・・・

End Sub

Aベストアンサー

参考になるかな?

セッションオブジェクトを作成する
https://www.ibm.com/support/knowledgecenter/ja/SSVRGU_8.5.3/com.ibm.designer.domino.main.doc/H_ACCESSING_THE_DOMINO_OBJECTS_THROUGH_COM_CREATING.html

QExcelVBAを使って、値がある場合は作業を繰り返し実行するプログラムを作成したい。

以下のようなプログラムをVBAで作成したいと考えています。

A1のセルに値があれば、その値をB1に返す。
次にA2のセルに値があれば、その値をB2に返す。
A行に値がある一番下のセルまで同じようなことをさせたいと考えています。

VBAは初心者です。
どなかた宜しくお願い致します。

Aベストアンサー

#2さんと似たものですが・・・・参考にしてください。

Sub test001()
Dim i As Long
i = 1
Do While Cells(i, 1) <> ""
Cells(i, 2) = Cells(i, 1)
i = i + 1
Loop
End Sub

QExel VBA 別ブックから該当データを検索し、必要なデータを取得する方法について

部品表というブックがあります
A列に商品名、B列に商品番号が入力してあります。C列のコードは未入力です。
A列     B列     C列      
商品名  商品番号  コード
モータ  U-1325-L  
ホルダ  R-134256

また、コード一覧表という別のブックには、A列に商品番号と、B列にコードが、何千件も入力されています。

やりたいことは
部品表のC列のコード欄に、コード一覧表ブックから商品番号と一致するコードを貼り付けしたいのです。

部品表は、何百種類もありますので、関数ではなく、マクロで処理を希望します。

自分では、部品表の商品番号をコピーして、コード一覧表で検索し、検索結果の右隣のセル(B列のコード)の値を部品表のC列に貼り付ければよいかと思い、書いてみたんですが…

Sub 別ブックから貼り付ける()
  Dim 検索する As Long
Windows("部品表.xls").Activate
検索する = cells(i,2).Value
Windows("コード一覧表.xls").Activate
ActiveWindow.SmallScroll Down:=-3
Selection.AutoFilter Field:=3, Criteria1:="=検索する", Operator:= xlAnd

と、してみたものの、検索しても、その検索結果の隣のセルのコードをどうやって取得すればいいのかが、わかりませんでした。

基本事項は本で学びましたが、呪文のようなコードはよく理解できません。懸命にネットで検索して、訳して理解する努力をしてはいますが。

どうぞよろしくお願いします。

部品表というブックがあります
A列に商品名、B列に商品番号が入力してあります。C列のコードは未入力です。
A列     B列     C列      
商品名  商品番号  コード
モータ  U-1325-L  
ホルダ  R-134256

また、コード一覧表という別のブックには、A列に商品番号と、B列にコードが、何千件も入力されています。

やりたいことは
部品表のC列のコード欄に、コード一覧表ブックから商品番号と一致するコードを貼り付けしたいのです。

部品表は、何百種類もありますので、関数...続きを読む

Aベストアンサー

こんにちは。
とりあえず実用性も踏まえました。
メインの動作はワークシート関数のVLOOKUPをVBA上で使用していますので理解はしやすいかと思います。
また、質問文から察するに「部品表.xls」と「コード一覧表.xls」の両方を開いて処理されていますが「コード一覧表.xls」はプログラム内で開いて閉じているので実行するときは「コード一覧表.xls」は閉じて置いてください。
Option Explicit
Sub Sample()
 Application.ScreenUpdating = False
 Dim I As Long
 Dim xlBook
 Set xlBook = Workbooks.Open("C:\★★\コード一覧表.xls") '★要変更★
 I = 2
 Do While Range("A" & I).Value <> ""
  ThisWorkbook.Worksheets("Sheet1").Range("C" & I).Value = Application.VLookup(ThisWorkbook.Worksheets("Sheet1").Range("B" & I).Value, xlBook.Worksheets("Sheet1").Range("A2:B65535"), 2, 0)
  I = I + 1
 Loop
 xlBook.Close
 Application.ScreenUpdating = True
 MsgBox ("完了")
End Sub

こんにちは。
とりあえず実用性も踏まえました。
メインの動作はワークシート関数のVLOOKUPをVBA上で使用していますので理解はしやすいかと思います。
また、質問文から察するに「部品表.xls」と「コード一覧表.xls」の両方を開いて処理されていますが「コード一覧表.xls」はプログラム内で開いて閉じているので実行するときは「コード一覧表.xls」は閉じて置いてください。
Option Explicit
Sub Sample()
 Application.ScreenUpdating = False
 Dim I As Long
 Dim xlBook
 Set xlBook = Workbooks....続きを読む

QVBA DO LOOP Do loopをつかって行を空欄まで見に行き、ある条件の時は行を削除します。

VBA DO LOOP

Do loopをつかって行を空欄まで見に行き、ある条件の時は行を削除します。ただdo loopでさくじょすると行が動くので(四行目を削除すると五行目が四行目になり、四行目が条件対象であっても四行目はループしているため、プログラムが見に行かない。)うまくいきません。何か他の方法でうまくいきませんか?

Aベストアンサー

No.2さんと同じ考えかたです。
A列をA1から見ていって、1の行を削除します。

Sub Sample()
  Dim row As Long
  
  row = 1
  Do While Cells(row, 1).Value <> ""
    If Cells(row, 1).Value = 1 Then
      Cells(row, 1).EntireRow.Delete
      row = row - 1
    End If
    row = row + 1
  Loop
End Sub

QVB上で実行中の無限ループの止め方

今まで、CUIベースのBASICでのプログラムの経験はあるのですが
Visual系のBASICは初心者です。
原因はわかっているのでプログラムの修正はできるのですが
VB上でコンパイルして実行したときに無限ループに陥ってしまって
どうにもプログラムをとめられなくなります。
そんなことがないように、実行前に全てのプロジェクトを保存して
いますので、そんなに実害はないのですが、どうすればとめられるのでしょう・・
今現在は、タスクマネージャーから強制終了させています。

Aベストアンサー

無限ループの一番内側に
DoEvents
を入れておくと、ウィンドウ切替え->デバッガ終了操作が出来ますよ

危なそうなとこにも入れておくと、何かと安心です。

QVBAで3の倍数の乱数を取得する

excelのVBAのことなのですが
3の倍数で整数で乱数を取得する方法がわかりません。

これがどうしてもわからなくて困ってます。
教えてください。

Aベストアンサー

60~198のの範囲の3の倍数の乱数を発生させ、A1からA1000のセルにその値を書き込んでいます。
200は3の倍数にならないので198を上限にしています。
MyRandを呼び出すと60から198の範囲の3の倍数の乱数を返します。
(あなたが実際に使うのは、MyRandだけです)
上限を201にしたいなら、66を67に変えてください。
MyRandを呼び出す前にRandomizeを1回実行してください。そうしないと毎回同じ結果が返ります。
---------------------------------
Option Explicit
Public Sub 乱数作成()
Dim i As Long
Dim r As Long
'乱数を作成しA列へ格納する(1000回分)
Randomize
For i = 1 To 1000
r = MyRand()
Cells(i, 1).Value = r
Next
End Sub

'60から198の範囲内の3の倍数の乱数を生成する。
Public Function MyRand() As Long
MyRand = Int((66 - 20 + 1) * Rnd + 20) * 3
End Function

60~198のの範囲の3の倍数の乱数を発生させ、A1からA1000のセルにその値を書き込んでいます。
200は3の倍数にならないので198を上限にしています。
MyRandを呼び出すと60から198の範囲の3の倍数の乱数を返します。
(あなたが実際に使うのは、MyRandだけです)
上限を201にしたいなら、66を67に変えてください。
MyRandを呼び出す前にRandomizeを1回実行してください。そうしないと毎回同じ結果が返ります。
---------------------------------
Option Explicit
Public Sub 乱数作成()
Dim i As Long
...続きを読む

Qexclelのvba逆引き辞典について

これにほぼvbaのコードが網羅されるくらいほとんど載っていますでしょうか。

Aベストアンサー

質問の答えとしては、ご質問者のレベルに依存するかと思います。
別の質問のWeb コントロールなどを試みているなら、そうした専門書もあるようですが、逆引きに収録されることはありません。

翔泳社の『VBA逆引き辞典』
ふつうのユーザーが満足できるレベルにはあるかと思います。この書籍は、VBAエキスパート試験を考慮に入れたものだそうで、どうも小技が目立つような気がします。VBAは、もともと小技の連発ですから、VBAを覚えるつもりなら、お勧めかもしれません。

秀和の『ExcelVBA逆引き大全』という本もあります。
個人的には、どうも、File System Object や正規表現までサポートしているなら、こちらの方が長いあいだ使えそうだと思いますが、VBAも、いきなり高いレベルに足を踏み入れても手も付かないと思います。私は、このシリーズ(VBA, VB.Net, VB6, VC++)を持っていますが、正確さには今ひとつ落ちるけれども、最初の導入部分では、助かることが多いです。

しかし、「VBA全般」という点では、私たちが想像するよりも、遥かに難しいし、資料もさっぱり手に入りません。

それと、VBAの原点は、VB6であるということは忘れてはならないことです。VB6の書籍で役に立つと思えば、古本屋さんでもよいので、何冊か手に入れることもよいと思います。特に、アルゴリズムに関係するものは、VBAで、ネットで書いている人がいますが、わざとイレギュラーな書き方をしていて、最初から読んで組み込まないと分からないような書き方になっていたりしています。外国のものもほとんど役に立ちません。VB6で書かれたものは、かなりのレベルで移植することが可能です。

質問の答えとしては、ご質問者のレベルに依存するかと思います。
別の質問のWeb コントロールなどを試みているなら、そうした専門書もあるようですが、逆引きに収録されることはありません。

翔泳社の『VBA逆引き辞典』
ふつうのユーザーが満足できるレベルにはあるかと思います。この書籍は、VBAエキスパート試験を考慮に入れたものだそうで、どうも小技が目立つような気がします。VBAは、もともと小技の連発ですから、VBAを覚えるつもりなら、お勧めかもしれません。

秀和の『ExcelVBA逆引き大全』という本も...続きを読む


人気Q&Aランキング

おすすめ情報