プロが教える店舗&オフィスのセキュリティ対策術

Private Sub CommandButton1_Click()
If Cells("選択範囲").SpecialCells(xlcellTypeblank).Select Then
Range("選択範囲").Value = 0
End If

End Sub

このマクロを作成したのですが、動きません。
どこが、おかしいのでしょうか?

A 回答 (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
    • good
    • 1
この回答へのお礼

実際やってみました。
違いがまだわかりませんが、どちらでもうまくいきました。
もっと経験を積んで失礼にならないくらいになりたいです。
こんな骨なしに時間を無駄にしたと思われないようにがんばります。

お礼日時:2007/02/04 23:47

#5 の訂正です



#今回は、便宜的に使います。
は、
・VBAでは、本来は、・・・・
の末尾につけてください。便宜的に「名前-定義」を使います。

ということでした。そのままでは、意味が通りません。
    • good
    • 0

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)です。
    • good
    • 0
この回答へのお礼

すいません。丁寧な解説ありがとうございます。
とにかく、VBAを覚えようと思って、何でもかんでも自動化を試しています。
経験を積むことが大事かなと思って。

お礼日時:2007/02/04 23:23

#1です。



If Cells("選択範囲").SpecialCells(xlcellTypeblank).Select Then

End If
の2行はいりません。念のため。
    • good
    • 0

Private Sub CommandButton1_Click()


  Range("選択範囲").SpecialCells(xlCellTypeBlanks).Value = 0
End Sub
単純にこれでよろしいのでは?
    • good
    • 0
この回答へのお礼

確かにこれで行きました。
ありがとうございます。

お礼日時:2007/02/04 23:20

構文が変です。



Range("選択範囲").SpecialCells(xlCellTypeBlanks).Value = 0
    • good
    • 0

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

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A