• ベストアンサー

エラー値を含み、空白以外の場合を識別したい

エクセル2000です。 A1セルがエラー値を含み、空白以外の場合を識別したいのですが、以下のように回りくどく書く以外に良い方法があったらお教えください。 空白とは関数によって "" が表示されている場合と、まったくの空白の両方のことです。 Sub test() Dim buf As Boolean buf = IsError(Sheets("Sheet1").Range("A1")) If Not (buf) Then buf = Sheets("Sheet1").Range("A1").Value <> "" End If If buf Then MsgBox "該当しちゃいました。" End If End Sub

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

  • ベストアンサー
  • end-u
  • ベストアンサー率79% (496/625)
回答No.1

回りくどいというか、段階的に判定しているので、良いのではないでしょうか。 常套的だと思えるのですが。 コードの意図が理解できますし。 仮に MsgBox Len(CStr(Sheets("Sheet1").Range("A1").Value)) > 0 ...こういう書き方だとちょっとわかりにくいですよね。

merlionXX
質問者

お礼

ありがとうございます。 MsgBox CStr(Sheets("Sheet1").Range("A1").Value) <> "" でもOKでした。

その他の回答 (5)

  • end-u
  • ベストアンサー率79% (496/625)
回答No.6

ちょっと気になったので書いておきますね。 >質問者のmerlionXXさんへ 私は、貴方が無礼な書き方をしたとか回答者が不愉快な思いをしたとか思いません。 あまりお気になされませんように。 質問のポイントを再度まとめると ・セルがEmptyの場合 ・セルの値が数式の結果 "" となる、長さ0の文字列の場合 を除く全てのケースを True と判定したい。 この時、セルには(数式の結果)エラーもあり、これも True としたい。 エラー値があるため buf = Sheets("Sheet1").Range("A1").Value <> "" この判定ではエラー値の場合は型違いのエラーが発生するので 事前にIsError関数で判定していて回りくどく書いている。 他に良い方法はないか。 提示はしませんでしたがエラー対策なら Dim flg As Boolean On Error Resume Next flg = (Len(Selection.Value) > 0&) MsgBox (Not flg) これでもいいわけです。 でも私が言いたかったのは If TypeName(Selection) <> "Range" Then Exit Sub With Selection   MsgBox Len(.PrefixCharacter & CStr(.Value)) > 0& End With これと Dim flg As Boolean Dim v  As Variant Dim s  As String If TypeName(Selection) <> "Range" Then Exit Sub With Selection   v = .Value   s = .PrefixCharacter End With If Not IsError(v) Then   If Len(s & CStr(v)) = 0& Then     flg = True   End If End If MsgBox (Not flg) これで、『そのコードの意図するところがどちらが読み取れますか?』的な事が言いたかった事でした。 CStr関数を使ってエラー値を文字列に変換して長さをチェックする事で、エラー値をもTrue判定できますが、 元々、そのコードを見た時に 『そもそもエラー値を想定しているのかどうか、エラー値の場合どう扱うのか想定しているのか』 前者ではわかりにくいと思います。 コメントを書けば良いという問題でもないと思いますがどうでしょう。 それから以下余談になってしまいますが、 >DisplayZerosプロパティがFalseの時のゼロ値など。 >Valueで判定したほうが良い状況もあるかもしれません。 どうも私のこの蛇足が「ダメ出し」でして、ご迷惑をおかけしました。申し訳ございませんでした。 『値を判定したい場合はTextプロパティは使わないほうが良いと思います』 と書けば良かったでした。 質問内容からして、表示形式が弄られてないという事が担保されているならともかく、 Textプロパティの性質上、表示文字列の取得やチェックは適していますが、 値有無チェックには適さないというだけです。 後だし条件とも、ダメ出しとも思えません。 完璧な質問も完璧な回答もあり得ませんから、文章のやり取りを重ねて、 また、試行錯誤を重ねて、対応していけばいいだけのような気がします。 お互いが気配りする事でそのやり取りの手間が少なくて済む事は確かですけどね。

merlionXX
質問者

お礼

ありがとうございます。 ご配慮痛み入ります。 今後ともご指導くださいますようお願い申し上げます。

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

特に回答ではありません。 >ただ、ユーザーによっては0を非表示としている場合もあるのでやはりVALUEを使い、 ユーザーによって? 恣意的にその書式の表示を換えるわけではないと思いますから、その条件が最初にあるなら、私の回答では違うと思います。ただ、それを、もし、私が知らないと思い私のコードを添削したのでしたら、ありがとうございます。それに気が付かなかった私に非はありますが、掲示板の後だし条件として、前もって、出されることを予想してコードを書くには、かなり厳しいと思います。それに、全条件に満ちた条件式を求め、そうでないものにダメ出しするのは、質問としても、ご自身に対しても無理があるかと思います。(分かって貰えるかしらね。) それと、本来、その判定するセルは、数式があるか、ないかという条件によっても違ってくるような気がします。こういうことは、後だししたらキリがありません。 元のご質問をあわせるなら、#4さんの回答で良いと思います。後になってみて、私も同じようなコードを考えました。私個人は、実務上では際立ったテクニックを追うほど失敗が多いものです。MsgBox の代わりに、Flug を置いても良いと思います。それが一般的な解答だと思います。それに対して、気に入る・気に入らないの反応はご自由ですが、ダメ出しは付けられないと思います。 単に、エラー値は、他の文字比較を排他的にしてしまうので、最初に、別に扱うという考え方でよいと思います。これは、IIf では使えない典型的な例だと思います。実務としては、現実に、ひとつのセルに対して、そういう判定するのではなく、SpecialCells で、最初に採って、そこから、判定条件を出せば済むように思います。それは、同じ原理です。

merlionXX
質問者

お礼

Wendy02さま、いつもお世話になりありがとうございます。 どうも無礼な書き方をしてしまったようで、大変申し訳なく存じます。 「ユーザーによって」というのはわたしの作成したエクセルファイルを使用する社員が複数いるためで、その人たちがオプションで0を非表示にしているか否かわたしには把握できないからです。 また、このことは、セルのVALUEではなくTEXTで見るWendy02さまのご回答を見て、0表示のことにはじめて思い当たったのです。 結果として「後だし」になってしまったことは御詫び申し上げます。 ご回答いただいた方々に不愉快な思いをさせ、すみませんでした。

  • KURUMITO
  • ベストアンサー率42% (1835/4283)
回答No.4

エラー値の場合や空白以外(式による空白も含む)の場合に該当と表示させるマクロでしたら次のようにしてもよいでしょう。 Sub test() If IsError(Sheet1.Range("A1")) = True Then MsgBox "該当" ElseIf Sheet1.Range("A1") <> "" Then MsgBox "該当" End If End Sub

merlionXX
質問者

お礼

ありがとうございます。 ただこの方法だと、まったく同じ「MsgBox "該当"」 (実際にはもっと長いコード)を二つも書かなければならないのが難点です。

  • end-u
  • ベストアンサー率79% (496/625)
回答No.3

蛇足です。すみません。 DisplayZerosプロパティがFalseの時のゼロ値など。 Valueで判定したほうが良い状況もあるかもしれません。 レアケースであるのは間違いないですが。

merlionXX
質問者

お礼

はい、やってみて気づきました。 Sub test() ActiveWindow.DisplayZeros = False MsgBox CStr(Sheets("Sheet1").Range("A1").Value) <> "" End Sub ありがとうございます。

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

こんばんは。 >回りくどく書く以外に良い方法があったら VBAは、関数の数式と違います。数式には人格(権)がありません。しかしプログラミング・コードには、回りくどくても、それがmerlionXXさん自身の今のコードだと思います。問題がなければよいとするしかないと思います。 ただ、ご質問のコードは、ロジックとしては、端的にいうと(空白以外) だと思います。 従って、(空白以外)なら、すべて該当するということになりますね。 しかし、Value 値では、Text 比較が出来ませんから、以下のようにします。 Sub Test2() With Worksheets("Sheet1")  If .Range("A1").Text <> "" Then    MsgBox "In case!"  Else    MsgBox "Not Found"  End If End With End Sub

merlionXX
質問者

お礼

ありがとうございます。 ただ、ユーザーによっては0を非表示としている場合もあるのでやはりVALUEを使い、 Sub Test3() With Worksheets("Sheet1") If CStr(.Range("A1").Value) <> "" Then MsgBox "In case!" Else MsgBox "Not Found" End If End With End Sub としてみました。

関連するQ&A

  • VBA空白を除いてコピーが出来ません。ご指導お願いします。

    値のコピー&ペースト(空白を除いてコピー)したいと思っております。 シート1 の A35、D35、I35 をコピー。 シート2 の A2 に貼り付け。 これは、大丈夫です。 シート1 の M2 : O23 をコピー。 シート2 の E2 に貼り付け。 今回の場合ですと、M2 : O13 までに値が入ってます。 ですので、M14 : O23 までが、空白になって記入となってしまいます。 *毎回、値が入る量が違います。 一回のコピーですと、これでもいいのですが、 値を変更して、コピーを続けてしますので、M14 : O23 までが、空白になってM24からのコピーになってしまいます。 空白を除いて、貼り付けしたいのですが、 どうすればいいのかわかりません。 お分かりになる方、ご指導よろしくお願いします。 VBAは以下になっております。 Sub Macro1() ' Application.ScreenUpdating = False Sheets("Sheet1").Range("A35,D35,I35").Copy If Sheets("Sheet2").Range("A2").Value = "" Then Sheets("Sheet2").Range("A2").PasteSpecial Paste:=xlPasteValues Else Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues End If Sheets("Sheet1").Range("M2:O23").Copy If Sheets("Sheet2").Range("E2").Value = "" Then Sheets("Sheet2").Range("E2").PasteSpecial Paste:=xlPasteValues Else Sheets("Sheet2").Range("E" & Rows.Count).End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues End If Application.CutCopyMode = False Application.ScreenUpdating = True End Sub よろしくお願いします。

  • 印刷後のVBAの実行 (3)

    Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name = "Sheet1" Then If Range("D6").Value = "" Then Cancel = True MsgBox ("名前を入力してください") Range("D6").Select Exit Sub End If Else If ActiveSheet.Name = "Sheet2" Then If Range("C11").Value = "" Then Cancel = True MsgBox ("受付時間を入力してください") Range("C11").Select Exit Sub End If Else Exit Sub End If End If If Worksheets("Sheet1").Range("D5") = "不要" Then GoTo P1 ActiveSheet.Range("A70:Y70").Copy If Worksheets("Sheet3").Range("A1").Value = "" Then Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues Else Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _ Paste:=xlPasteValues End If Application.CutCopyMode = False P1: ActiveSheet.Range("A1").Select End Sub sheet1のD5に「不要」と入っていたら 24~33行目の作業がキャンセルになりますが sheet2のD5にも「不要」と入っていたら、同じ様にキャンセルできる様に出来ますでしょうか? ご回答お願いします

  • 【Excel VBA】ワークシートの表示(続き)

    すみません。 追記が出来なかったため、コードの続きをこちらに記載します。 For i = 1 To 12 If actsht = tmp(i) Then Flag = 1 Anser = MsgBox("翌月分シートを作成しますか?", vbYesNo + vbDefaultButton1, "確認") If Anser = vbYes Then ActiveSheet.Copy After:=ActiveSheet ActiveSheet.Name = tmp(i + 1) Sheets(actsht).Tab.ColorIndex = 2 Sheets(actsht).Range("B3").Value = Sheets("Sheet2").Range("A1").Value Sheets(actsht).Range("B4").Value = Sheets("Sheet2").Range("A2").Value ActiveSheet.Range("A2").Select Exit For ElseIf Anser = vbNo Then Exit For End If End If Next If Flag = O Then MsgBox ("新しいワークシートを作成出来ません。") End If If actsht = tmp(i) Then If Sheets(元データ).Visible = False Then Sheets(元データ).Visible = True End If End If End Sub

  • 印刷後のVBAの実行 (2)

    Private Sub Workbook_BeforePrint(Cancel As Boolean)   If ActiveSheet.Name = "Sheet1" Then     If Range("D6").Value = "" Then       Cancel = True       MsgBox ("名前を入力してください")       Range("D6").Select       Exit Sub     End If   Else     If ActiveSheet.Name = "Sheet2" Then       If Range("C11").Value = "" Then         Cancel = True         MsgBox ("受付時間を入力してください")         Range("C11").Select         Exit Sub       End If     Else              Exit Sub     End If   End If   ActiveSheet.Range("A70:Y70").Copy   If Worksheets("Sheet3").Range("A1").Value = "" Then     Worksheets("Sheet3").Range("A1").PasteSpecial Paste:=xlPasteValues   Else     Worksheets("Sheet3").Range("A65536").End(xlUp).Offset(1, 0).PasteSpecial _       Paste:=xlPasteValues   End If   Application.CutCopyMode = False   ActiveSheet.Range("A1").Select End Sub 先日、上記のコードを回答者の方から教えてもらい、とても助かっていますが sheet1のD5に「不要」という文字が入っていた場合、 sheet3への貼り付け(23~30行目の作業)をキャンセルして、最後にsheet1のA1を選択するようにはどの様にしたらいいでしょうか?

  • Excelでシート名と最終更新日を自動表示したい

    Excelを使って (1)セルA1に入れた名目をシート名にし (2)セルH1には、最終更新日を自動で入れたいです。 調べた結果、 シート名を右クリックして「コードの表示」から (1)は Private Sub Worksheet_Change(ByVal Target As Range) Sheets(1).Name = Range("B1") End Sub を入れてうまくいきましたが、 (2)は Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)  If ThisWorkbook.Saved = False Then   Worksheets("Sheet1").Range("H1").Value = Date  End If End Sub を入れてみましたが(←調べましたもの) うまくいきませんでした。 単純に、 Private Sub Worksheet_Change(ByVal Target As Range) Sheets(1).Name = Range("B1") End Sub Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)  If ThisWorkbook.Saved = False Then   Worksheets("Sheet1").Range("H1").Value = Date  End If End Sub とつなげて入れるのではだめなんでしょうか? それとも、(2)の何かが間違っていますか? ご教授願います。

  • Excel VBA セルの双方向同期のエラーについ

    エラーが発生して理由がわからないので、どなたか助言をお願いします。 以下のVBAにて、目的のセルにデータを入力すると、1回目は必ず添付写真の通りのエラーが出まして、デバッグをすると3行目が黄色でハイライトされます。 記述は以下の通りです。どうぞよろしくお願いします。 シートAへのVBA設定 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$A$1" Then Sheets("シートB").Range("$B$1").Value = Sheets("シートA").Range("$A$1").Value End If End Sub シートBへのVBA設定 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$B$1" Then Sheets("シートA").Range("$A$1").Value = Sheets("シートB").Range("$B$1").Value End If End Sub

  • エクセル マクロ エラー

    Sub 保存() Dim MySheetName As Variant MySheetName = InputBox("シート名を入力してください") If MySheetName = "" Then Exit Sub Sheets("1").Copy After:=Sheets(Worksheets.Count) ActiveSheet.Name = MySheetName Sheets("原本").Range("A1:K73").Copy Sheets("1原本").Range("A1") End Sub シートにグラフを乗せたらエラーが出たのですが 解除できないでしょうか?

  • エクセル チェックボックスの解除について(VBA)

    YES/NOを入力させる為の下記のVBAにおいて、チェックボックス1をチェックすると、アの部分でチェックボックス2の解除を行う関係で?、シート上でチェックボックス2を操作していないのにもかかわらず、勝手にCheckBox2_Click()に入り、命令文イを実行してしまいます。 ただ単にSub CheckBox1_Click()のルーチンの最後までの処理で終わりたいのですが、どうしたらよいのでしょうか。 Private Sub CheckBox1_Click() If CheckBox1 = True Then Sheets("sheet1").Range("A1") = 1 Sheets("sheet1").Range("A2") = 0 CheckBox2 = False・・・ア Else Sheets("sheet1").Range("A1") = "" End If End Sub Private Sub CheckBox2_Click() If CheckBox2 = True Then Sheets("sheet1").Range("A1") = 0 Sheets("sheet1").Range("A2") = 1 CheckBox1 = False Else Sheets("sheet1").Range("A2") = ""・・・イ End If End Sub

  • エクセルVBAの不思議な挙動?

    エクセル2003です。 ThisWorkbookには以下の記述があります。 Private Sub Workbook_BeforePrint(Cancel As Boolean) If ActiveSheet.Name <> "Sheet1" Then Exit Sub If Range("A1").Value = "" Then MsgBox "A1が未入力です" Range("A1").Select Cancel = True End If Application.OnTime Now(), "ページ移動" End Sub 標準モジュールには以下の記述があります。 Sub ページ移動() Sheets("Sheet2").Select Range("A1").Select End Sub Sub プリント() ActiveWindow.SelectedSheets.PrintPreview End Sub これでSheet1を開いた状態でツールバーから印刷プレビュー指示をすると、A1セルが入力済みであればプレビュー画面を出し、プレビューを閉じればSheet2が表示されます。 ところが、同じ状態でツールバーからではなく、マクロ Sub プリント を実行すると、プレビュー画面にはなりますが、プレビューを閉じてもSheet1のままです。 なぜ、 Application.OnTime Now(), "ページ移動" が、有効にならないのでしょうか?

  • 「 このコード 」 のチェック を お願い致します。

    下記コードは何とか動作しますが、チェックお願い致します。 1、 MsgBox "「 空白シート 」 は ありません。"    の    追加編集が、よくわかりません。 2、 1以外に、おかしな箇所をご教示お願い致します。 --------------------------- '「 ブック1 」 に空白シートがあったら、そこへ貼り付ける Sub 空白シートへコピー() Dim ws As Worksheet For Each ws In Workbooks("ブック1.xls").Sheets If IsEmpty(ws.UsedRange) = True Then Workbooks("ブック2.xls").Activate Cells.Select Selection.Copy Workbooks("ブック1.xls").Activate ws.Select Range("A1").Select ActiveSheet.Paste Else MsgBox "「 空白シート 」 は ありません。" End If Next End Sub

専門家に質問してみよう