エクセル2000で、あるセルが空白なら警告メッセージボックスを出して
保存できないようにする、というプログラムをVBAで作りました。
VBEで一行ずつ走らせるとちゃんとメッセージボックスが
出てくるのですが、実際にブックからD6を空白にしたまま保存しようと
したらメッセージボックスが出てこずに保存できてしまいます。
どこかで、設定が必要なのでしょうか?

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

With Worksheets("sheet1")

If .Range("D6").Value = "" Then
MsgBox "please enter D6 field.", vbCritical, "警告"
Cancel = True
End If

End With

End Sub

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

A 回答 (1件)

こんにちは。

maruru01です。
fuyuさんのコードを、ThisWorkbookにそっくりそのまま貼り付けて実行したら、うまくいきました。
このコードはThisWorkbookにあるんですよね。
でしたら後は、D6が空白ではなく、スペースが入っているとか。
今のところ他にうまく行かない例が見つかりません。
ちなみに、D6に「= D1」とセル参照が入っていて、D1が空白で結果的にD6も空白の場合でも、やはり空白と認識し、警告してくれます。
あと、Range("D6")の「D6」を「D6」と全角にしてもOKでしたし、
"sheet1"と"Sheet1"が違ってもOKでした。
では。
    • good
    • 0
この回答へのお礼

なぜだか分かりませんが、時間がたつとちゃんと動きました。回答ありがとうございました。

お礼日時:2001/10/10 18:35

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

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

QPrivate Sub Workbook_BeforeSaveについて

エクセル2000です。
腑に落ちない現象が起きているので質問させてください。
Sheet1にテキストボックス(OLEオブジェクトのTextboxではありません)とボタンが貼ってあり、Visble=Falseで非表示にしています。それを保存する際には表示させたいので、BeforeSaveイベントで

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Sheet1.TextBoxes("テキスト").Visible = True
Sheet1.Buttons("ボタン").Visible = True
MsgBox "保存されちゃった!"
End Sub

と書いてみました。
手動で保存する場合には正しく、テクストボックスやボタンは正しく表示されます。もちろんMsgboxも出ます。

ところが、標準モジュールに書いた以下のコード、

Sub 保存()
ActiveWorkbook.Save
End Sub

を走らせてみても、"保存されちゃった!"と、Msgboxは出ますが、肝心のテクストボックスやボタンが表示されません。
試行錯誤の結果、
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Sheet1.Shapes("テキスト").Visible = True
Sheet1.Shapes("ボタン").Visible = True
MsgBox "保存されちゃった!"
End Sub

と書くと、標準モジュールから、ActiveWorkbook.Saveでも表示されることがわかりました。
どうしてでしょうか?

エクセル2000です。
腑に落ちない現象が起きているので質問させてください。
Sheet1にテキストボックス(OLEオブジェクトのTextboxではありません)とボタンが貼ってあり、Visble=Falseで非表示にしています。それを保存する際には表示させたいので、BeforeSaveイベントで

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Sheet1.TextBoxes("テキスト").Visible = True
Sheet1.Buttons("ボタン").Visible = True
MsgBox "保存されちゃった!"
End Sub

と...続きを読む

Aベストアンサー

>を走らせてみても、"保存されちゃった!"と、Msgboxは出ますが、肝心のテクストボックスやボタンが表示されません。

ユーザー関数を抜けて「シートが待ち状態になるまで」は、シート上の子コントロールのVisibleプロパティの変化は反映されません。

ところが「セーブしちゃうと、Visibleプロパティが変化したのを忘れてしまう」ので「Sub 保存()を抜け、Visibleプロパティの変化が反映されるタイミング」には、もう「Visibleプロパティが変化したのを忘れている」のです。

つまり、Sub 保存()を抜けるまで、Visibleプロパティを変化させても反映されません。

しかし、ShapesのVisibleプロパティは「見た目だけを即座に画面に反映する」ので、Visibleプロパティを変更した瞬間に画面に反映されます(但し、反映されるのは「見た目だけ」なので、そのコントロールがクリック可能とは限りません)

Q標準モジュールで 『Sub test(ByVal Target As Range)』は動かない?

選択されている複数のアドレスが知りたいので
標準モジュールに
Sub test(ByVal Target As Range)
Debug.Print Target.Address
End Sub
と書きました。

しかしF5ボタンを押しても何も起こりません。
デバッグ→コンパイルをしてもエラーになりません。

シートのイベントプロシージャーではなく
標準モジュールにした理由は
イベント発生時ではなく、任意で起動させたいためです。

ためしに、
Sub test(ByVal Target As Range)
Debug.Print Target.Address
End Sub
の下に、

Sub test2()
Call test
End Sub

と書いたら、
「引数は省略できません。」
というエラーになりました。

何がダメなのかわかりません。
ご教授よろしくお願い致します。

Aベストアンサー

こんばんは。

今回は、初歩的なことですが、段階を経たほうがよいと思います。つまみ食いのようなことをしても、なかなか、VBAもWSHも覚えられないと思います。しかし、今回のように単発では、こちらの書いていることはほとんど分かってもらえないと思います。

今回は、サブルーチンのコードですが、サブルーチンを書くということは、それなりに、その前段階を理解していなくてはなりません。イベント・ドリブン型とは関係がありません。

それと、Target は、予約語ではありませんが、イベント・ドリブン型の引数に使われているものですから、他の語を使ったほうがよいです。それを許していると、自分ですらコードが読めなくなっていくはずです。

今回のようなコードを実際に書くことはありえませんが、ByVal キーワードは、入れるのと入れないのでは違いがありますが、Test1 側で、引数のデータ型が決めてあれば、入れなくても構わないです。Debug.Print としてしまったら、さっぱり、その意味が見えないでしょうけれども……。

F5を押しても、サブルーチンは呼び出さないと動きません。
それに、呼び出す場合は、引数を入れなければなりません。

'-------------------------------------------

Sub Test1()
Dim c As Range  '←これがあるので、ByVal は不要
For Each c In Range("A1:A10")
 Call Test2(c)
Next c
End Sub

'サブルーチン(Target という名称は使わない)
Sub Test2(rng As Range)
  Debug.Print rng.Address
  'Debug.Print では、良く意味が分からないはずです。
  'Range オブジェクトを引数にしたら、いろんな使い方がある
End Sub

'-------------------------------------------

こんばんは。

今回は、初歩的なことですが、段階を経たほうがよいと思います。つまみ食いのようなことをしても、なかなか、VBAもWSHも覚えられないと思います。しかし、今回のように単発では、こちらの書いていることはほとんど分かってもらえないと思います。

今回は、サブルーチンのコードですが、サブルーチンを書くということは、それなりに、その前段階を理解していなくてはなりません。イベント・ドリブン型とは関係がありません。

それと、Target は、予約語ではありませんが、イベント・ドリブン...続きを読む

QExcelVBA With~End With構文でまとめられない??

すみませんがご教示いただければ幸いです。
セル範囲を選択させ、情報を得てから作業するのですが、コードにたくさんSelection(すべて同じ選択範囲)が出てくるのでWith~End Withでまとめようと思いました。
ところが、まとめてもSelectionという表記を省略できたのはほんのわずかです。
ご覧の通り、TypeName(Selection) をはじめIntersect(Selection(1), 等々省略できないのがほとんどです。
Set myRng=Selection でやったとしても、SelectionがmyRngに変わるだけでぜんぜん省略にならないですよね?
こんな場合は何か別の省略した書き方があるのでしょうか?

Sub test()
With Selection
If TypeName(Selection) <> "Range" Then 'セル以外をセレクトしてたら
MsgBox "セル範囲を選択してください。", vbCritical, " Σ( ̄ロ ̄lll)"
Exit Sub
End If
If Intersect(Selection(1), Range("D4:AY65")) Is Nothing _
Or Intersect(Selection(.Count), Range("D4:AY65")) Is Nothing Then '指定のセル範囲をはみ出てたら
ans = MsgBox("はみ出してますがいいんですか?", vbYesNo + vbQuestion, " ( ̄□ ̄; ? ")
If ans = vbNo Then
Exit Sub
End If
End If
For Each Ln In ActiveSheet.Lines '配置された各直線につき
If Not Intersect(Range(Ln.TopLeftCell, Ln.BottomRightCell.Offset(0, -1)), Selection) Is Nothing Then '選択範囲とかぶってたら
MsgBox "重複してます!", vbCritical, " ( ̄□ ̄;)!! "
Exit Sub
End If
Next
End With
'以下、無関係なので略します。
End Sub

すみませんがご教示いただければ幸いです。
セル範囲を選択させ、情報を得てから作業するのですが、コードにたくさんSelection(すべて同じ選択範囲)が出てくるのでWith~End Withでまとめようと思いました。
ところが、まとめてもSelectionという表記を省略できたのはほんのわずかです。
ご覧の通り、TypeName(Selection) をはじめIntersect(Selection(1), 等々省略できないのがほとんどです。
Set myRng=Selection でやったとしても、SelectionがmyRngに変わるだけでぜんぜん省略にならないですよね?
...続きを読む

Aベストアンサー

こんばんは。

結論からすると、With Selection ~ End With の必要性は、あまり出てきませんね。
Selection というスタイル自体が特殊ですから、まとめても不恰好になってしまいます。

With Selection というのは、Excel では、あまり品番に出てこないように思います。
こういう書法の原則というのは、文字数を減らすということなのだと私は解釈しています。だから、一応、以下は、その目的自体は達成はしているように思います。

TypeName の部分は除いて、「はみ出してます」に関してのみ、少し考えてみました。まずは、参考まで。


Sub TestSample1()
  Dim r As Range
  Set r = Range("D4:AY65")
  ''--TypeName は省略--
  With Selection
    If .Areas.Count > 1 Then
       MsgBox "複数の範囲を選択しています。ひとつにしてください。"
       Exit Sub
    End If
    If Not Intersect(.Cells, r) Is Nothing Then
      If (.Cells(1).Row >= r(1).Row And .Cells(.Cells.Count).Row <= r.Cells(r.Count).Row) And _
        (.Cells(1).Column >= r(1).Column And .Cells(.Cells.Count).Column <= r.Cells(r.Count).Column) Then
        MsgBox "範囲内に入っています。"
      Else
        MsgBox "範囲からはみ出ています。"
      End If
    Else
      MsgBox "範囲外です。"
    End If
  End With
End Sub

こんばんは。

結論からすると、With Selection ~ End With の必要性は、あまり出てきませんね。
Selection というスタイル自体が特殊ですから、まとめても不恰好になってしまいます。

With Selection というのは、Excel では、あまり品番に出てこないように思います。
こういう書法の原則というのは、文字数を減らすということなのだと私は解釈しています。だから、一応、以下は、その目的自体は達成はしているように思います。

TypeName の部分は除いて、「はみ出してます」に関してのみ、少し考えて...続きを読む

QEXCEL VBA コンボボックス、テキストボックスが未入力のときメッセージを表示する方法

ユーザーフォームにコンボボックス2個textboxが2個あります
コンボは選択のみです。
コンボとtextbox1は入力必須にして、空欄でコマンドボタンが押された時はメッセージを表示したいです
OKwebを参考に作ったのですが、コンボ1が空欄でもMsgが出ません
願いします

Private Sub CommandButton1_Click()
Dim ctrl As Control, tst1 As String, txt2 As String
Dim ws As Worksheet

Set ws = Sheets("sheet1")
For Each ctrl In Me.Controls
Select Case ctrl.Name
Case "ComboBox1", "ComboBox2", "TextBox1"
If Me.Controls(ctrl.Name).Value = "" Then
txt1 = txt1 & ctrl.Name & vbLf
Else
txt2 = txt2 & Me.Controls(ctrl.Name).Value & vbLf
End If
End Select
Next
If Len(txt1) > 0 Then
MsgBox "以下の値を入力してください" & vbLf & txt1, vbExclamation
Exit Sub
Else
ret = MsgBox("以下の値を入力します" & vbLf & txt2, vbOKCancel)
If ret <> vbOK Then Exit Sub

ユーザーフォームにコンボボックス2個textboxが2個あります
コンボは選択のみです。
コンボとtextbox1は入力必須にして、空欄でコマンドボタンが押された時はメッセージを表示したいです
OKwebを参考に作ったのですが、コンボ1が空欄でもMsgが出ません
願いします

Private Sub CommandButton1_Click()
Dim ctrl As Control, tst1 As String, txt2 As String
Dim ws As Worksheet

Set ws = Sheets("sheet1")
For Each ctrl In Me.Controls
Select Case ctrl.Name
Case "ComboBox1", "ComboBox2", "...続きを読む

Aベストアンサー

こんにちは。

バグらしいバグは掲載されたソースからは読み取れません。ComboBox に
どのようにデータを追加しているのか、どのようなデータなのかあたり
からも検証しないと。

また、ソースが途中で途切れてますよ。ちゃんと End Sub まで、掲載して
下さい。

とりあえず、新規ブックで Userform を挿入し、

 ・Textbox1
 ・ComboBox1
 ・ComboBox2
 ・CommandButton1

をそれぞれ配置してから、下記ソースを貼り付けて動かしてみて下さい。

Private ws As Worksheet

Private Sub UserForm_Initialize()
  
  Set ws = Sheets("sheet1")
  
  ' // ComboBox 用テストデータ作成
  ws.Cells.Delete
  With ws.Range("A1:C10")
    .Formula = "=""R""&ROW()&""C""&COLUMN()"
    .Value = .Value
  End With
  With ws.Range("D1:D10")
    .Formula = "=""ITEM""&ROW()"
    .Value = .Value
  End With
  ' // 選択 ONLY のコンボボックス(fmStyleDropDownList)に
  ' // データを追加する
  With Me.ComboBox1
    .Style = fmStyleDropDownList
    .ColumnCount = 2
    .List = ws.Range("A1:C10").Value
  End With
  With Me.ComboBox2
    .Style = fmStyleDropDownList
    .List = ws.Range("D1:D10").Value
  End With

End Sub

' // Style が fmStyleDropDownList のコンボボックスで値を消去できるようにする
Private Sub ComboBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  If KeyCode = 8 Or KeyCode = 46 Then ' 8:backspace / 46: delete key
    ComboBox1.ListIndex = -1
  End If
End Sub
Private Sub ComboBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
  If KeyCode = 8 Or KeyCode = 46 Then ' 8:backspace / 46: delete key
    ComboBox2.ListIndex = -1
  End If
End Sub

Private Sub CommandButton1_Click()

  Dim ctrl As Control, txt1 As String, txt2 As String
  Dim ret As Integer
  
  For Each ctrl In Me.Controls
    Select Case ctrl.Name
      Case "ComboBox1", "ComboBox2", "TextBox1"
        If Len(Trim$(ctrl.Text)) = 0 Then
          txt1 = txt1 & ctrl.Name & vbLf
        Else
          txt2 = txt2 & ctrl.Text & vbLf
        End If
      Case Else
    End Select
  Next
  
  If Len(txt1) > 0 Then
    MsgBox "以下の値を入力してください" & vbLf & txt1, vbExclamation
    Exit Sub
  Else
    ret = MsgBox("以下の値を入力します" & vbLf & txt2, vbOKCancel)
    If ret <> vbOK Then Exit Sub
  End If

End Sub

追伸:: ....余計なお世話ですが。

■1点目: 変数名が違います。

> Dim ctrl As Control, tst1 As String, txt2 As String

txt1 As String ですよね。このようなミスを防ぐ意味で、Option Explicit
を宣言のうえ、プログラムを作成する習慣をつけた方が、上達が速いですよ。

■2点目: For Each ループについて

For Each ctrl In Me.Controls のループで

> Me.Controls(ctrl.Name).Value

とするのは、折角 For Each を使う意味が無くなってしまいますから、
そのまま ctrl.value とか、ctrl.text で使って下さい。

こんにちは。

バグらしいバグは掲載されたソースからは読み取れません。ComboBox に
どのようにデータを追加しているのか、どのようなデータなのかあたり
からも検証しないと。

また、ソースが途中で途切れてますよ。ちゃんと End Sub まで、掲載して
下さい。

とりあえず、新規ブックで Userform を挿入し、

 ・Textbox1
 ・ComboBox1
 ・ComboBox2
 ・CommandButton1

をそれぞれ配置してから、下記ソースを貼り付けて動かしてみて下さい。

Private ws As Worksheet

Private Sub ...続きを読む

QEndモードにしないEndキー

EXCELでEndキーを押すと,ステータスバーに「END」モードの表示が出ます。ENDモードにしないで,アクティブセルと同じ行の一番右端(データの含まれている範囲で)に移動させるにはどうしたら良いのでしょうか?
EXCEL2000です。

Aベストアンサー

こんにちは。

以下のマクロで、試してみて下さい。

Private Sub auto_Open()
Application.OnKey "{END}", "Set_EndColumn"
End Sub
Sub Set_EndColumn()
wRow = ActiveCell.Row
Range("IV" & wRow).End(xlToLeft).Select
End Sub

'マクロ貼付
(1) Alt+F11 (ツール → マクロ → Visual Basic Editor) →「挿入」→「標準モジュール」で表示される画面に貼り付け
(2) Excelを再起動して試しください。


人気Q&Aランキング

おすすめ情報