- ベストアンサー
選択範囲の空白セルに0を入れるマクロ
Private Sub CommandButton1_Click() If Cells("選択範囲").SpecialCells(xlcellTypeblank).Select Then Range("選択範囲").Value = 0 End If End Sub このマクロを作成したのですが、動きません。 どこが、おかしいのでしょうか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 実際にやってみましたが、考えていたよりも遥かにむつかしいですね。 このSpecialCells のコードのレベルは、意外にも、かなり上級になってしまうかもしれません。今回は、便宜的に使います。 確かに、記録マクロで作れるレベルですが、思わぬ落とし穴が一杯あります。 私が、最初に考えていたコード(BlankToZero) ・VBAでは、本来は、なるべく、ワークシートの「名前-定義」は、あまり使わないほうがよいです。「名前-定義」がエラーでもぐりこんでしまうと、VBAでは触れられなくなってしまいます。 ・SpecialCells(xlCellTypeBlanks)は、以下のような、エラートラップ必要です。 (1) Sub BlankToZero() Dim r As Range 'SpecialCells のブランク探しは、エラートラップが必要です On Error Resume Next '名前-定義でつけられたもの,オブジェクトの中にシート情報があるので、芳しくない Set r = Range("選択範囲").SpecialCells(xlCellTypeBlanks) On Error GoTo 0 If Not r Is Nothing Then r.Value = 0 End If 'オブジェクトの開放 Set r = Nothing End Sub しかし、これでは、本当に成功はしません。それは、SpecialCells は、あくまでも、UsedRange の範囲しか受けつけてくれませんので、いくら、「名前-定義」があっても、正しく、「0」は入らない時があります。 したがって、どうやら、.SpecialCells(xlCellTypeBlanks) は、万能ではなさそうです。(うまくいく場合は、あくまでも、UsedRangeに、その範囲が入っている場合のみです) 以下のようなものからやってみてください。なるべく、ワークシートで使われるメソッドは、ミスやトラブルが多いので、実践を何度も積んでからのほうがよいです。私は、今回は、たまたま気がついただけです。 次が改良型(BlankToZeroRvs) '標準モジュールのみ Sub BlankToZeroRvs() Dim c As Variant '画面を更新させないと、処理スピードが劇的に速くなります Application.ScreenUpdating = False For Each c In Range("選択範囲") If IsEmpty(c) Then c.Value = 0 End If Next c Application.ScreenUpdating = True End Sub
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
#5 の訂正です #今回は、便宜的に使います。 は、 ・VBAでは、本来は、・・・・ の末尾につけてください。便宜的に「名前-定義」を使います。 ということでした。そのままでは、意味が通りません。
- imogasi
- ベストアンサー率27% (4737/17069)
Cells("選択範囲").SpecialCells(xlcellTypeblank) すなわち指定範囲の空白セルを Selectしてセル群のオブジェクト(Range)を掴み、 それのValueプロパティに対して、値0を代入する。 -- xlcellTypeblank はxlcellTypeblanksのミス -- Cells("選択範囲")はRange(選択範囲)が正しい RangeとCellsの関係を勉強すること ーー 例えば Sub test01() Range("A1:C10").Select Selection.SpecialCells(xlCellTypeBlanks).Select Selection.Value = 0 End Sub ーー 以下は参考に IFは不要ということに関連して SpecialCells(xlcellTypeblank)を使うことにより、IF文的な選択は内部的に行われるので、VBAのスクリプト上はIF文は要りません。 この機能がVBAなどスクリプトを使えば、IF文の繰り回しを表現せずに、実質IFを多数回数繰り回ししたのと同じになります。 それでコードがすっきりします。 For Each Cl In Rande(範囲) If Cl="" Then ・・ と言ったコードに比べれば、すっきりします。 ですから (1)VB的コード法(他言語のプログラム経験あり、エクセルVBAの 本を余り読んでないタイプの人に多い) (2)エクセル固有のプロパティを使うコード法 (3)もっと凝ったやり方(いつもあるとは限らないが有るかも) もうひとつ例を挙げると、Findメソッドを使うと(2)にあたり 各セルをIF文で同じか聞いて、全行走査するのが(1)です。 エクセルの関数をVBAで使うのも(2)です。例えば平均で、合計をだし、データ数で割って出すのは(1)です。
お礼
すいません。丁寧な解説ありがとうございます。 とにかく、VBAを覚えようと思って、何でもかんでも自動化を試しています。 経験を積むことが大事かなと思って。
- merlionXX
- ベストアンサー率48% (1930/4007)
#1です。 If Cells("選択範囲").SpecialCells(xlcellTypeblank).Select Then と End If の2行はいりません。念のため。
- bonaron
- ベストアンサー率64% (482/745)
Private Sub CommandButton1_Click() Range("選択範囲").SpecialCells(xlCellTypeBlanks).Value = 0 End Sub 単純にこれでよろしいのでは?
お礼
確かにこれで行きました。 ありがとうございます。
- merlionXX
- ベストアンサー率48% (1930/4007)
構文が変です。 Range("選択範囲").SpecialCells(xlCellTypeBlanks).Value = 0
お礼
実際やってみました。 違いがまだわかりませんが、どちらでもうまくいきました。 もっと経験を積んで失礼にならないくらいになりたいです。 こんな骨なしに時間を無駄にしたと思われないようにがんばります。