質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

290閲覧

セル範囲で数式上のエラーの判定

SugiuraY

総合スコア317

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2019/02/25 02:30

編集2019/02/25 03:05

A1:B1 =IF(C1="hoge","error1","")
A2:B2 =IF(C2="fuga","error2","")
A3:B3 =IF(C3="foo","error3","")
A4:B4 =IF(C4="bar","error4","")

上記のように、結合した4つのセルに一定の条件を満たせばエラー出力され、そうでなければ
空白を返す数式によるエラー判定が存在します。

やりたいこととしては、A1:B4に少なくとも一つエラーがあればprintをcancelさせるとともに
MsgBoxでエラー内容を出力させ、そうでなければ、プリント出力を許可するようにしたいと考えております。

下記のコードで意図した動作をさせることができなません。

具体的に

  1. ErrMsgに1つでもエラー内容文字列が出力された場合に、エラーを出力したいのに常に出力されます。

*検証してみるとIf UBound(ErAry) > 1 ThenにもかかわらずErAryの個数は常に4が出力されておりこの理由がわかりません。
2) エラー内容を出力するためのmsgBoxについても空の文字列が出力されてしまい、例えばError1とError2を識別している場合には
"Error(*1)が解消されていませんError(*2)が解消されていません"とMsgBox出力することを意図しているのに、何も出力されません。

宜しくお願い申し上げます。

vba

1Private Sub Workbook_BeforePrint(Cancel As Boolean) 2 3 Dim ErAry(4) As String 4 If Worksheets("入力").Cells(1, 1).Value <> "" Then 5 ErAry(1) = "Error(*1)が解消されていません" 6 End If 7 If Worksheets("入力").Cells(2, 1).Value <> "" Then 8 ErAry(2) = "Error(*2)が解消されていません" 9 End If 10 If Worksheets("入力").Cells(3, 1).Value <> "" Then 11 ErAry(3) = "Error(*3)が解消されていません" 12 End If 13 If Worksheets("入力").Cells(4, 1).Value <> "" Then 14 ErAry(4) = "Error(*4)が解消されていません" 15 End If 16 17Dim c 18Dim ErrMsg As String 19If UBound(ErAry) > 1 Then 20 Cancel = true 21 For Each c in ErAry 22 ErrMsg = ErrMsg + c 23 Next c 24 MsgBox ErrMsg 25EndIf 26 27 28 29End Sub

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttyp03

2019/02/25 02:38

何が実現できていないのか明確に記入してください。
SugiuraY

2019/02/25 03:06

コメントありがとうございます。 具体的にという個所に明確化させていただきました。
guest

回答2

0

ベストアンサー

配列にしてややこしくする必要はないかと。

VBA

1 Dim ErrMsg As String 2 ErrMsg = "" 3 If Worksheets("入力").Cells(1, 1).Value <> "" Then 4 ErrMsg = ErrMsg & vbCrLf & "Error(*1)が解消されていません" 5 End If 6 If Worksheets("入力").Cells(2, 1).Value <> "" Then 7 ErrMsg = ErrMsg & vbCrLf & "Error(*2)が解消されていません" 8 End If 9 If Worksheets("入力").Cells(3, 1).Value <> "" Then 10 ErrMsg = ErrMsg & vbCrLf & "Error(*3)が解消されていません" 11 End If 12 If Worksheets("入力").Cells(4, 1).Value <> "" Then 13 ErrMsg = ErrMsg & vbCrLf & "Error(*4)が解消されていません" 14 End If 15 16 If ErrMsg <> "" Then 17 Cancel = True 18 MsgBox Mid(ErrMsg, 3) '先頭の改行を除去 19 End If

投稿2019/02/25 03:20

sazi

総合スコア25195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2019/02/25 06:04

コメントありがとうございます。 先入観でエラーメッセージを結合するには配列化してから、要素を足し合わせるべきとおもっていたのですが、シンプルな解決方法をご教示いただきありがとうございます。 申し訳ございませんが、一点だけコードで理解できなかったため、教えてください。 「vbCrLf mid」等で検索してもわからなかったのですが、なぜmidでstart引数に3を指定すると初めの改行を削除することができるのでしょうか?
sazi

2019/02/25 06:13 編集

vbCrLfは、改行(Cr)+ラインフィールド(Lf)で2文字としてカウントされます。 複数のエラーがあった場合に、改行を付加するしないの判断を入れるとややこしいロジックになるので、一律付加しておき、先頭の改行は余分なものとして除去します。 mid()のパラメータは、mid(対象文字列, 開始位置[,文字列長])で、文字列長を省略すると文字列の最後までが対象になります。
SugiuraY

2019/02/25 06:42

ありがとうございす、よくわかりました。 "改行(Cr)+ラインフィールド(Lf)で2文字"という知識がなかったので、非常に勉強になりました! 宜しくお願い申し上げます。
guest

0

VBA

1Foreach c in ErAry

vbaだとFor Each 空白が必要

VBA

1For Each c in ErAry

VBA

1ErrMsg = ErrMsg + ErAry

ErAryのデータをcに入れて処理しているので

VBA

1ErrMsg = ErrMsg + c

投稿2019/02/25 02:52

date

総合スコア1820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2019/02/25 03:07

コードミスについて、ご指摘いただきありがとうございます。 修正したのですが動作しなかったため、「具体的に」以降で内容を加筆させていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問