重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

お世話になってます。
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

よろしくお願いいたします。

質問者からの補足コメント

  • どうもありがとうございました。
    試してみました。
    まさに、リンク先の延長です。
    1)こちらは動作問題ありません。思い通り実行され自動で閉じました。変更の意味も分かりました。
    2)こちらは、一応エラーこそなく実行もされているように見えますが、なぜか消えていないですね。
    ローカルウィンドウの'n'の中身が若干違います。
    画像添付いたします。左が1)のやり方の時で、右が2)のやり方の時の結果です。

    「エクセルvbaで、開いている名前の管理画」の補足画像1
    No.1の回答に寄せられた補足コメントです。 補足日時:2016/07/02 10:46
  • "_xlfn*"は、確かエクセル2007以上か何かで、「IFERROR」関数等の何らかの該当する関数を使っていると、名前に"_xlfn*"というものが見えない状態で登録されていて、値や参照範囲が”#NAME?"となっているため、途中に、”RefersToRange.Parent.Name”などのコードを使っていると、これを削除するだけであっさり動くものでも、エラーになったり思い通りに動かなかったりの問題があったように思います。
    Application.SendKeysについては、先に記述しておくんですね。逆の書き方なのでステップで見ていってもなかなか意味が分かりませんでした。

    No.2の回答に寄せられた補足コメントです。 補足日時:2016/07/02 11:26
  • 補足続きです。で、
    Application.SendKeys "%{F4}", Trueもついでに試してみましたが、閉じるには閉じるんですが、"_xlfn*"が残ったままでその後の続きのコードで突如終了しており思い通りに動きませんでした。
    なぜか、続きに記述してある
    If n.RefersToRange.Parent.Name = "xxxx" Then
    の所で、突然終了してしまっていました。№1の回答の2)の時もそのようになっていました。次ステップのn.Deleteを実行するわけでもなくEnd IfにいくわけでもなくEnd Subすら実行せずに終了している様子でした。
    なので、№1の回答の1)でするしかダメみたいですね。

      補足日時:2016/07/02 11:27

A 回答 (3件)

こんにちは



よくわかっていませんが、ちょっと調べてみました。

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
 こちらも通常の名前ではテストしていますが、問題となっている見えない名前が削除できるのかは不明です。

※ 両方ともうまくいかない場合は、上記の既存回答に出ている削除方法を試してみるのがよろしいかと思います。
(若干長いコードですが・・・)
この回答への補足あり
    • good
    • 0
この回答へのお礼

どうもありがとうございました。

お礼日時:2016/07/04 22:00

私からの結論を申し上げておきます。



[2015-07-06]というファイルが残っていましたので、その作った時の原本の記録から見て思い出してはいるのですが、もともと、このマクロ自体が、対話型で手動で行うような設計なのでした。ですから、本来、その趣旨を変えるということにもなるかと思いますが、作者の私としては、なんとも申し上げられません。

この開発の時に、その手の問題は浮かんだことは間違いないのですが、Excel2003時代とは違って、その手立てが見つからなかったことも事実ですし、これ以上、コードを複雑にしするつもりもありませんでした。
ある意味では、SendKeys は苦肉の策です。

#1さんの回答でよろしければ、私としては、私のあずかり知らないものとして、そのままスルーさせていただきたく思います。

今後、それが、Sendkey を、[名前の管理(Name Manager)」のハンドルを取ってSendMessageやPostMessageで仮想キーを送るようにしたところで、元の趣旨そのものは変わらないと思います。できる出来ないは別として、対話型ダイアログを閉じる手段は、いくつか知られていますが、対話型そのものを否定することになるのだろうと思います。

この件については、
>If n.RefersToRange.Parent.Name = "xxxx" Then
の所で、突然終了してしまっていました。№1の回答の2)の時もそのようになっていました。

一旦、終了してしまったマクロを、途中からつなぎ合わせる方法がないわけではありませんが、仮にできても、すでに、私が書く話などは不要なのかと存じます。

いずれ、こうした流れの中で、マクロで全面的に書き換える人は、出てくるでしょうし、その時は、私も新たな気持ちで向き合うことにはするつもりです。

ただ、今のところ、Excel自身にバグが存在しなければ済むという根本的な問題以外は、技術の違いこそあれ、どれも大差がないのではないか、と思っています。

もともと、イレギュラーな問題に対して、それを辛うじて、面倒な作業をマクロで行う以上に、私としては、それを更に便利なものにするつもりはなかったわけです。言い訳めいているように思えますが、1年前と、それほどに考え方は変わっているわけではありません。

あまり、意味のある書き込みではありませんでした。
    • good
    • 0
この回答へのお礼

どうもありがとうございました。

お礼日時:2016/07/04 21:59

回答者本人です。



"_xlfn*"
この件は、覚えていますが、細かいことは、もう一度読み直さないと思い出せません。なかなかややこしい内容だったと思います。

Excel 2007以上の関数を入れたセルの名前を登録して、エラーを出すと問題が発生してしまうということです。ただ、ご質問のマクロ自体は、緊急避難的なものです。

ダイヤログを自動で閉じるのは、少し、コンマ数秒の時間を置いて、

Application.SendKeys "%{F4}", True

で、閉じることは可能なのですが、できたら、これはこのままにさせていただきたく思っています。

以下のマクロの意味は、本来、マクロの手順としては逆でして、Dialog が出た後、溜めていた命令で、削除する処理ものなのです。

本来は、手動でやっていただく所を、マクロで無理矢理に行っているだけの話です。

Application.SendKeys "%D{ENTER}", True
Application.Dialogs(xlDialogNameManager).Show

> [expression].Names(n.Name).Delete
これができれば、それに越したことはありません。
それができないから問題があるのです。
名前の登録には、マクロでしか解決できないものと、手動でしか解決しないものと二種類あるようです。

今回のものは、一旦消したつもりでも、再び復活してくる「ゾンビ・オブジェクト」なのです。

これは、言葉の説明が難しいので、あえてマクロにしたものです。
ある種、これは、バグのひとつのようです。
この回答への補足あり
    • good
    • 0
この回答へのお礼

どうもありがとうございました。

お礼日時:2016/07/04 22:00

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