
エクセル2000です。
ある大きな表のうち、0値を非表示ではなく完全に削除するために以下のようなマクロを書いてみました。
一旦配列に取り込んでいるのは高速化のためです。
これで見た目には目的を達しているのですが、実際には0値が長さ0の文字列に変わっただけで完全な空白にはなっていません。
配列にとりこまず、セルをループして0値のセルをClearすれば解決するのはわかるのですが、ほかにいい方法はないでしょうか?
Sub TEST0値()
Dim myAr
With ActiveSheet
x = .Range("A" & Rows.Count).End(xlUp).Row
myAr = .Range("A4:AP" & x).Value
For i = LBound(myAr, 1) To UBound(myAr, 1)
For n = LBound(myAr, 2) To UBound(myAr, 2)
If myAr(i, n) = 0 Then myAr(i, n) = ""
Next n
Next i
.Range("A4:AP" & x).Value = myAr
End With
End Sub
No.9
- 回答日時:
こんにちは
以前、関連した質問に回答していたもので、気になりまして。
宿題の邪魔になってしまうかも知れませんが
やや混乱されてるようにお見受けしたので。
merlionXXさんが以前から気になさっていたのは
たしか、こういうことではなかったかと、、、
Sub test()
With Range("B2")
.NumberFormatLocal = "@"
.Value = ""
MsgBox [istext(b2)]
.Value = Empty
MsgBox [istext(b2)]
Dim Arr(0)
.Value = ""
MsgBox [istext(b2)]
.Value = Arr
MsgBox [istext(b2)]
End With
End Sub
これ、回答じゃなくて、遅ーい、夏のご挨拶ってことで(^^;)
この回答への補足
この質問とはちがいますが、昨年の10月に別件で
> ただ、Value = "" を使うと、セル書式が文字列になっている場合、完全な空白ではなくなるようで、ISBLANKがFALSEなのにCOUNTBLANKでは空白に数えられるという不整合がおきます。それでClearContentsするようにしています。
なんて、自分で書いているんですね!?
すっかり忘れていました。
その際にもcj_moverさまには大変お世話になり、ありがとうございました。
cj_moverさま、いつもありがとうございます。
な~るほどぉ~っ!
セル書式が文字列になっていると、VBAで Value = "" とすると、長さ0の文字列が入って空白にはならないんですね。
その点、Value = Empty なら、書式に関係なく大丈夫ということですね。
ありがとうございました。
これで安心して夏休み(明日から4連休!蓼科~軽井沢)がとれます!
No.8
- 回答日時:
こんにちは。
No.3,4,6です。> Microsoft Scripting Runtime を参照していない環境だと
> Dim myDic As Scripting.Dictionary がエラーになってしまいました。
処理を実行する前のコンパイルチェックで Scripting.Dictionary オブジェクトが見つからないからです。
ですから「これを使いますよ」って参照設定しておくのです。
> Dim myDic As Object だとエラーになりません。
処理を実行する前のコンパイルチェックでは、オブジェクトなら何でもいいと宣言しているのでエラーになりません。実行時の参照設定で WorkSheet が入ろうと、Scripting.Dictionary が入ろうともExcelは関知しないのです。
そして、処理が実行され、Set myDic = CreateObject("Scripting.Dictionary") の行にきて初めて "Scripting.Dictionary"オブジェクトを使うと分かり、Microsoft Scripting Runtime ライブラリを探してmyDicに参照設定します。
これが実行時バインディングというものです。その時点で Microsoft Scripting Runtime ライブラリが見つからない時は、エラーになります。
事務所で書類を作成している時に、必要な資料がなくて書庫に探しに行くようなものです。資料がなければ作業を中断せざるを得ません。
> 参照しない場合は Dim myDic As Object でやるしかないということですね。
そうなります。As Object のことは、CreateObject 関数のヘルプにきちんと書かれています。
ですが、Scripting.Dictionary を使おうとしていて、参照設定できる環境にあるのにあえて As Object と宣言して参照設定のメリットを享受しない理由が判りません。
処理を速くしたいと思ってコードを組んでいるのなら、参照設定してきちんとオブジェクトの型を宣言すべきと私は思います。
> そして、処理が実行され、Set myDic = CreateObject("Scripting.Dictionary") の行にきて初めて "Scripting.Dictionary"オブジェクトを使うと分かり、Microsoft Scripting Runtime ライブラリを探してmyDicに参照設定します。
なるほど、そういうことだったんですか。
そんなことも知らずに使っていました。
勉強になりました。
今回はわたしの勘違い質問でしたが、ずいぶん多くを学ぶことが出来ました。
OtenkiAmeさん、ありがとうございます。
皆様、ありがとうございます。
No.7
- 回答日時:
>みなさま大変おさがわせいたしました。
いえ、いえ、かまいませんよ。
お騒がせ大好きです。。。(^^;;;
ただ、ある条件のもとでは質問の件のように
""を代入することで、長さ0の文字列が入る場合があります。
で、当方の回答はそれを考慮しての回答でした。
要するに、未入力の状態にするということです。
さてさて、この【ある条件】とは何でしょう。
ま、これは夏休みの宿題、ということで。。。(^^;;;
以上です。
【ある条件】?
Sub Test1()
With Range("A1")
.Formula = "="""""
.Copy
.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End With
MsgBox IsEmpty(Range("A1"))
End Sub
ということではなく、配列で入れた場合の話ですよね?
何でしょう?!
夏休み終わってしまいました・・・・。
No.6
- 回答日時:
こんにちは。
No.3、No.4です。> これはどのような違いがあるのでしょうか?
> Newがついてるので何か違うのでしょうがわかりません。
Newキーワードは、オブジェクトのインスタンスを実際に作成させるために記述しています。
詳しいことは、VBAのヘルプファイルのCreateObject関数の項目とSetステートメントの項目をご一読いただくと良いかと思いますが、私の場合、もし使用するオブジェクトが分かっているなら、変数の宣言の段階でオブジェクトを宣言するようにしています。
これは、事前バイディングと実行時バインディングの違いによるもので、VBAを使い始めた頃に処理が高速になると教えられました。
例ですと
Dim myDic As Object
は、オブジェクトへの参照が実行されるまで何が入るか分からないですよね。
でも
Dim myDic As Scripting.Dictionary
なら、オブジェクトは明確に宣言されているので、処理が実行される前に変数の最適化が行われたり、コードを作成する時にオートメンバの機能などが使えます。
CreateObject関数を使うなら
Dim myDic As Scripting.Dictionary
Set myDic = CreateObject("Scripting.Dictionary")
として使用したほうが事前に変数が最適化されているので処理が速くなるということです。
高速な処理を目指すなら細かいことですけど、使用する変数は、型を含めてきちんと宣言しておくと良いと思います。
(少なくとも私はそうしています。)
ちなみに、CreateObject関数を使用するか、実際のオブジェクトを参照するかは、好みによるのかな?と思います。
「どちらが最適なのか」までは解説できる知識を持ち合わせていませんのであまり突っ込まないでくださいね。(^_^;)
ではでは。
なんどもありがとうございます。
> Dim myDic As Scripting.Dictionary
> Set myDic = CreateObject("Scripting.Dictionary")
> として使用したほうが
Microsoft Scripting Runtime を参照していない環境だと
Dim myDic As Scripting.Dictionary がエラーになってしまいました。
Dim myDic As Object だとエラーになりません。
参照しない場合はDim myDic As Object でやるしかないということですね?
No.5
- 回答日時:
んにちは。
>これで見た目には目的を達しているのですが、実際には0値が長さ0の文字列に変わっただけで完全な空白にはなっていません。
良く分からないですね。配列変数のVariant 型で、長さ0の文字列[""]であったとしても、
.Range("A4:AP" & x).Value = myAr
としたら、[""]をセルに代入したら、空になってしまうのでは?
例えば、Range("A1").Value = "" は、A1 は、空のはずです。
それとも、何か入っているのですか?
もし、セルに[""]を入れるなら、
Range("A1").Value = """"""
'-------------------------------------------
Sub EmptyTest1()
Range("A1").Value = ""
If IsEmpty(Range("A1")) Then
MsgBox "セルは空です。"
Else
MsgBox "何か残っています。"
End If
End Sub
'-------------------------------------------
わたしは何か、とんでもない勘違いをしていたようです。
計算結果で ="" になったセルを、コピーして値貼り付けした場合の現象が頭にあって、ためしもせずに質問してしまいました。
試したところWendy02さまのおっしゃる通りでした。
みなさま大変おさがわせいたしました。
ごめんなさい。
No.4
- 回答日時:
こんにちは。
No.3です。> 実際は0値のみならずさまざまな条件で空白にしたいので
それならDictionaryを使ってみては如何でしょうか?
'VBEのツール-参照設定で Microsoft Scripting RuntimeをチェックしてOK
Dim myAr As Variant
Dim x As Long, i As Long, n As Long
Dim myDic As Scripting.Dictionary
Set myDic = New Scripting.Dictionary
'辞書にKey(照合値)とItem(Keyと一致したときの要素)を追加
'例えば0,1,3,5を空にする
With myDic
.Add 0, Empty
.Add 1, Empty
.Add 3, Empty
.Add 5, Empty
End With
With ActiveSheet
x = .Range("A" & .Rows.Count).End(xlUp).Row
myAr = .Range("A4:AP" & x).Value
For i = LBound(myAr, 1) To UBound(myAr, 1)
For n = LBound(myAr, 2) To UBound(myAr, 2)
'辞書と照合してItem(ここではEmpty)を代入
If myDic.Exists(myAr(i, n)) Then myAr(i, n) = myDic(myAr(i, n))
Next n
Next i
.Range("A4:AP" & x).Value = myAr
End With
Set myDic = Nothing
ご丁寧にありがとうございます。
Dictionaryを使うことは思いもよりませんでした。
参考までに教えていただければ幸いですが、わたしがこれまで使ったことがあるDictionaryは、
Dim myDic As Object
Set myDic = CreateObject("Scripting.Dictionary")
のような記述ではじめるのですが、
Dim myDic As Scripting.Dictionary
Set myDic = New Scripting.Dictionary
これはどのような違いがあるのでしょうか?
Newがついてるので何か違うのでしょうがわかりません。
No.3
- 回答日時:
こんにちは。
置換したら如何でしょうか?
Dim x As Long
With ActiveSheet
x = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A4:AP" & x).Replace What:="0", Replacement:="", _
LookAt:=xlWhole, SearchOrder:=xlByRows, MatchCase:=False
End With
ありがとうございます。
たしかに質問の例の通り0値だけが対象ならこれでいけますね。
ただ、実際は0値のみならずさまざまな条件で空白にしたいので配列に取り込んだのです。
言葉足らずでもうしわけありませんでした。
No.1
- 回答日時:
多分コードは組める方だと思うのでヒントだけ。
データを取り込んで、「取り込んだ範囲を".clear"」
あとは、データのある部分だけ書き込み、という方法は如何かと。
さっそくありがとうございます。
データのある部分だけ書き込み、とはこういうことでしょうか?
これだとやはり個々にセルに入れるので時間がかかってしまいます。
Sub TEST0値2()
Dim myAr
With ActiveSheet
x = .Range("A" & Rows.Count).End(xlUp).Row
myAr = .Range("A4:AP" & x).Value
.Range("A4:AP" & x).ClearContents
For i = LBound(myAr, 1) To UBound(myAr, 1)
For n = LBound(myAr, 2) To UBound(myAr, 2)
If myAr(i, n) <> 0 Then .Range("A4:AP" & x).Cells(i, n) = myAr(i, n)
Next n
Next i
End With
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 稀に1円合いません? Sheet1から金額と個数を貼り付ける下記コードで、金額を切り上げるコードを何 3 2022/09/05 15:11
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
- Visual Basic(VBA) ExcelVBAのマクロについて。 9 2022/05/04 14:50
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- Visual Basic(VBA) VBA処理追加 こちらでご教示頂いたのですが回答完了させてしまいましたのでこちらからまた質問させてく 2 2022/10/27 09:57
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Visual Basic(VBA) Excel VBA キーワードから列を取得して、さらに空欄行を非表示にする 3 2022/10/21 22:49
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
このQ&Aを見た人はこんなQ&Aも見ています
-
空白への0入力 二次元配列(VBA)
Excel(エクセル)
-
Excelのセルの色指定をVBAから配列を用いて効率的に行う方法はあり
Visual Basic(VBA)
-
エクセル:マクロ「Application.CutCopyMode = False」って?
Excel(エクセル)
-
-
4
VBAでEmpty値って何ですか?
Excel(エクセル)
-
5
【VBA】ワークブックを開く時にエラーが出る場合と出ない場合の違いは?
Excel(エクセル)
-
6
表にフィルターをかけ、絞ったデータ(可視化セルのみ)を一次元配列として変数に入れるという動作を書きた
Visual Basic(VBA)
-
7
もしセルが#N/A"なら~をする・・・には?"
Excel(エクセル)
-
8
エクセルVBAで5行目からオートフィルタモードに設定したいたい
Excel(エクセル)
-
9
Excelのセルにユーザー名を表示する方法
Excel(エクセル)
-
10
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
11
エクセルへのデータの貼付時に書式が反映されない!
Visual Basic(VBA)
-
12
IF関数でEmpty値を設定する方法。
Excel(エクセル)
-
13
メッセージボックスのOKボタンをVBAでクリックさせたい
Visual Basic(VBA)
-
14
EXCEL VBA セルに既に入力されている文字に文字を追加する
Excel(エクセル)
-
15
Excel VBA Application.caller エラー2023について
Visual Basic(VBA)
-
16
ユーザーフォームに入力したデータを保持する方法
Visual Basic(VBA)
-
17
エクセルのマクロで指定条件一致行をグループ化したい
その他(Microsoft Office)
-
18
配列を任意の数値で埋める方法
Visual Basic(VBA)
-
19
VBAで配列の計算
Excel(エクセル)
-
20
array関数で格納した配列の型を変更する
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
エクセルのVBAの標準モジュール...
-
Excelでフィルタをかけると警告...
-
実行時エラー 3265「要求された...
-
VBScriptからDLL参照設定したい
-
VBAについてです。 初心者です...
-
VBAで既に開いている別アプリケ...
-
エクセルVBAで配列内に空白デー...
-
テキストボックス中の文字列の...
-
AccessVBAで「dim dbs as datab...
-
オブジェクト変数またはWITHブ...
-
ExcelVBAでのNZ関数について
-
Shell.ApplicationのNameSpace...
-
Excel VBA Collection.add で R...
-
列、行番号などをDebug.Printす...
-
InternetExplorer.Application...
-
VBA オブジェクトが空かどうか...
-
CreateObjectとGetObjectの違い
-
ExcelのVBAについて(グラフ操作)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
worksheetFunctionクラスのVloo...
-
「Columns("A:C")」の列文字を...
-
実行時エラー 3265「要求された...
-
エクセルのVBAの標準モジュール...
-
Excelでフィルタをかけると警告...
-
VBAで既に開いている別アプリケ...
-
テキストボックス中の文字列の...
-
EXCEL VBA オートシェイプナン...
-
VBAで Set wb = Sheets(1).Cop...
-
ExcelVBAでのNZ関数について
-
[VBA]CDOメッセージ送信エラー
-
VBAからPDFファイルにパスワー...
-
エクセルVBAでcode128のバー...
-
VBScriptからDLL参照設定したい
-
VBAについてです。 初心者です...
-
エクセルマクロエラー「'Cells'...
-
オブジェクトが見つかりません
-
エクセルVBAで配列内に空白デー...
-
Excel VBAでWordの複数ファイル...
-
VBScriptでファイルの日時順(降...
おすすめ情報