
お世話になってます。
Excel2013で、以下のようなコードがあります。これは、全体のごく一部を抜き出したものですが、これがないと思ったような動きにならないのですが、途中
Application.Dialogs(xlDialogNameManager).Show
で、名前の管理画面を呼びだしています。呼び出しますが、今の所、実際は何もせずに閉じています。
ですが、この部分をコメントアウトするとなぜかその後の結果が違ってくるので必要なのですが、この名前の管理画面を自動で閉じることはできるでしょうか?
また、どうして名前の管理画面を開いて閉じるだけで結果に違いがでるのでしょうか?
ついでに、その前の、Application.SendKeys "%D{ENTER}", Trueでは、何をしているのでしょうか?
Sub sample()
Dim n As Name
For Each n In ActiveWorkbook.Names
If n.Name Like "_xlfn*" Then
Application.SendKeys "%D{ENTER}", True
Application.Dialogs(xlDialogNameManager).Show
Exit For
End If
Next n
End Sub
よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
こんにちは
よくわかっていませんが、ちょっと調べてみました。
SendKeysはキー入力をシュミレートするものです。
"%D{ENTER}"はAlt+D、enterキーの入力を意味しますので、全体では"_xlfn*"に該当する名前があったら、削除するという操作と同じことを行っていることになります。
https://msdn.microsoft.com/ja-jp/library/office/ …
意味として何をやっているかというと、(↓)で論議されているようなことが目的と思われます。
(質問文にはご提示の無い、他の部分の処理との関係で必要なのかと推測されます)
https://oshiete.goo.ne.jp/qa/9019000.html
上記に削除の方法も出ているみたいですが、単純に名前の削除ではできないのかな?
見えない名前ということなので扱いにくいし、試験的に発生させることもうまくできないのでキチンと試せてはいないのですが、以下のどちらかで対応できるのではないでしょうか。
1)ダイアログを閉じるメソッドが見当たらないので、キー操作から閉じる
タブ+エンターを追加して
Application.SendKeys "%D{ENTER}", True
↓
Application.SendKeys "%D{ENTER}{TAB}{ENTER}", True
に変更。
ダイアログがちらりと見えますが、閉じるのではないでしょうか?
(通常の名前定義ではテストしています。)
2)ダイアログを用いず名前の削除メソッドで削除
ActiveWorkbook.Names(n.Name).Delete
こちらも通常の名前ではテストしていますが、問題となっている見えない名前が削除できるのかは不明です。
※ 両方ともうまくいかない場合は、上記の既存回答に出ている削除方法を試してみるのがよろしいかと思います。
(若干長いコードですが・・・)
No.3
- 回答日時:
私からの結論を申し上げておきます。
[2015-07-06]というファイルが残っていましたので、その作った時の原本の記録から見て思い出してはいるのですが、もともと、このマクロ自体が、対話型で手動で行うような設計なのでした。ですから、本来、その趣旨を変えるということにもなるかと思いますが、作者の私としては、なんとも申し上げられません。
この開発の時に、その手の問題は浮かんだことは間違いないのですが、Excel2003時代とは違って、その手立てが見つからなかったことも事実ですし、これ以上、コードを複雑にしするつもりもありませんでした。
ある意味では、SendKeys は苦肉の策です。
#1さんの回答でよろしければ、私としては、私のあずかり知らないものとして、そのままスルーさせていただきたく思います。
今後、それが、Sendkey を、[名前の管理(Name Manager)」のハンドルを取ってSendMessageやPostMessageで仮想キーを送るようにしたところで、元の趣旨そのものは変わらないと思います。できる出来ないは別として、対話型ダイアログを閉じる手段は、いくつか知られていますが、対話型そのものを否定することになるのだろうと思います。
この件については、
>If n.RefersToRange.Parent.Name = "xxxx" Then
の所で、突然終了してしまっていました。№1の回答の2)の時もそのようになっていました。
一旦、終了してしまったマクロを、途中からつなぎ合わせる方法がないわけではありませんが、仮にできても、すでに、私が書く話などは不要なのかと存じます。
いずれ、こうした流れの中で、マクロで全面的に書き換える人は、出てくるでしょうし、その時は、私も新たな気持ちで向き合うことにはするつもりです。
ただ、今のところ、Excel自身にバグが存在しなければ済むという根本的な問題以外は、技術の違いこそあれ、どれも大差がないのではないか、と思っています。
もともと、イレギュラーな問題に対して、それを辛うじて、面倒な作業をマクロで行う以上に、私としては、それを更に便利なものにするつもりはなかったわけです。言い訳めいているように思えますが、1年前と、それほどに考え方は変わっているわけではありません。
あまり、意味のある書き込みではありませんでした。
No.2
- 回答日時:
回答者本人です。
"_xlfn*"
この件は、覚えていますが、細かいことは、もう一度読み直さないと思い出せません。なかなかややこしい内容だったと思います。
Excel 2007以上の関数を入れたセルの名前を登録して、エラーを出すと問題が発生してしまうということです。ただ、ご質問のマクロ自体は、緊急避難的なものです。
ダイヤログを自動で閉じるのは、少し、コンマ数秒の時間を置いて、
Application.SendKeys "%{F4}", True
で、閉じることは可能なのですが、できたら、これはこのままにさせていただきたく思っています。
以下のマクロの意味は、本来、マクロの手順としては逆でして、Dialog が出た後、溜めていた命令で、削除する処理ものなのです。
本来は、手動でやっていただく所を、マクロで無理矢理に行っているだけの話です。
Application.SendKeys "%D{ENTER}", True
Application.Dialogs(xlDialogNameManager).Show
> [expression].Names(n.Name).Delete
これができれば、それに越したことはありません。
それができないから問題があるのです。
名前の登録には、マクロでしか解決できないものと、手動でしか解決しないものと二種類あるようです。
今回のものは、一旦消したつもりでも、再び復活してくる「ゾンビ・オブジェクト」なのです。
これは、言葉の説明が難しいので、あえてマクロにしたものです。
ある種、これは、バグのひとつのようです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
特定のPCだけ動作しないVBAマク...
-
エクセルで特定の列が0表示の場...
-
Excel・Word リサーチ機能を無...
-
メッセージボックスのOKボタ...
-
ExcelのVBA。public変数の値が...
-
【EXCEL VBA】オートシェイプを...
-
ExcelVBA 図形をクリックした...
-
一つのTeratermのマクロで複数...
-
マクロの連続印刷が突然不可能...
-
非表示の列をすべて削除するマクロ
-
【Excel】複数のマクロをまとめ...
-
エクセルに張り付けた写真のフ...
-
Excelで特定の文字のところで自...
-
UWLSの記録でマクロを作成し使...
-
アクセス マクロ クリップボ...
-
Excel_マクロ_現在開いているシ...
-
オートフィルターとExcelマクロ...
-
Excel マクロ VBA プロシー...
-
Excel 改ページのVBAうまくい...
-
コマンドボタンに二回目のマク...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで特定の列が0表示の場...
-
特定のPCだけ動作しないVBAマク...
-
メッセージボックスのOKボタ...
-
Excel_マクロ_現在開いているシ...
-
一つのTeratermのマクロで複数...
-
マクロの連続印刷が突然不可能...
-
ExcelのVBA。public変数の値が...
-
Excel マクロ VBA プロシー...
-
Excel・Word リサーチ機能を無...
-
エクセルに張り付けた写真のフ...
-
Excelのセル値に基づいて図形の...
-
TERA TERMを隠す方法
-
マクロ実行時エラー
-
ExcelVBAでPDFを閉じるソース
-
wordを起動した際に特定のペー...
-
特定文字のある行の前に空白行...
-
エクセルで縦に並んだデータを...
-
Excel マクロでShearePoint先の...
-
マクロ実行時、ユーザーフォー...
-
ソース内の行末に\\
おすすめ情報
どうもありがとうございました。
試してみました。
まさに、リンク先の延長です。
1)こちらは動作問題ありません。思い通り実行され自動で閉じました。変更の意味も分かりました。
2)こちらは、一応エラーこそなく実行もされているように見えますが、なぜか消えていないですね。
ローカルウィンドウの'n'の中身が若干違います。
画像添付いたします。左が1)のやり方の時で、右が2)のやり方の時の結果です。
"_xlfn*"は、確かエクセル2007以上か何かで、「IFERROR」関数等の何らかの該当する関数を使っていると、名前に"_xlfn*"というものが見えない状態で登録されていて、値や参照範囲が”#NAME?"となっているため、途中に、”RefersToRange.Parent.Name”などのコードを使っていると、これを削除するだけであっさり動くものでも、エラーになったり思い通りに動かなかったりの問題があったように思います。
Application.SendKeysについては、先に記述しておくんですね。逆の書き方なのでステップで見ていってもなかなか意味が分かりませんでした。
補足続きです。で、
Application.SendKeys "%{F4}", Trueもついでに試してみましたが、閉じるには閉じるんですが、"_xlfn*"が残ったままでその後の続きのコードで突如終了しており思い通りに動きませんでした。
なぜか、続きに記述してある
If n.RefersToRange.Parent.Name = "xxxx" Then
の所で、突然終了してしまっていました。№1の回答の2)の時もそのようになっていました。次ステップのn.Deleteを実行するわけでもなくEnd IfにいくわけでもなくEnd Subすら実行せずに終了している様子でした。
なので、№1の回答の1)でするしかダメみたいですね。