- ベストアンサー
Excelのセルに隠しラベルをつけたい
こんにちは。Excel2000で作業しています。 現在、あるボタンが押されたら、あるセルの値を参照するというコードをVBAで書いています。 この、参照するセルなのですが、場所が移動されても参照できるようにしたいのです。 例えば、コメントになにかユニークな値を記入することにより、その参照したいセルを検索することができると思いますが、コメントの場合、その値がユーザーから参照されたり編集できたりしてしまいます。 ユーザーから参照も編集もできない、VBAからのみ参照、編集可能なプロパティがあれば、目的を達することができそうなのですが、そのようなプロパティはありますでしょうか? 調べたところ、IDというプロパティがなにやら使えそうなのですが、ヘルプを見ると、HTML云々、Web云々といった解説がされています。 http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vbaxl11/html/xlproID.asp このIDプロパティというのは上記目的で使用しても大丈夫なのでしょうか。 その他、なにか方法がありましたら、ご教示願います。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>このIDプロパティというのは上記目的で使用しても大丈夫なのでしょうか。 IDに値を入れることはできるようですが、一旦BOOKをxls形式で保存すると消えてしまうみたいですね。ご自身でも確認してください。 (まずは自分で試してダメだったら聞くのが上達の早道ですよ) >場所が移動されても参照できるようにしたいのです 普通は「名前定義」を利用して、その名前でセル参照を行います これなら行挿入などによってセルアドレスが変わっても大丈夫です。 (名前定義の変更は可能ですが…) 例えばD1セルに「挿入」→「名前」→「定義」で「abc」という名前をつけて Msgbox Range("abc").value を実行してみてください。セルの場所が変わっても同じ値を返すはずです。
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 余計な口出しして、なおかつ、ご機嫌を損ねてしまったようです。 私は、何千というコードを書いていますが、そういう方法は取らないということです。初心者や中級レベルの方でないと、そのようなコードは書きません。どうして、そういう方法は書かないか理由を述べたわけですが、それが納得いかないのでしたら、それは、仕方がないです。 全体の構想が見せられていない以上は、厳密に、どうこう言えるものではありませんが、Name オブジェクトには、独特のトラブルを発生するものがあるということと、その位置の判定の仕方は、VBAには相応しい方法があるはずだということです。それは、最後まで内容が明かされていない以上は、その先は分かりませんが。 事実、Excel 2000 と名前定義の関係はあまり良くないし、状況によって、システムエラーまで起こすこともあるので、逆に、私に執拗に言って来た方もいます。名前定義に関する、いくつかの不可解な問題とか、そうなる条件というものを熟知していれば、問題はありませんが、それを知っていればこそ、私は、避ける方法を考えます。 基本的に、VBAのコーディングというよりも、プログラミングは、バグというよりも、そのコードの持つ基本的なエラーに対する想像力です。複雑とかいっても、ここで書いたレベルは、初歩の初歩の話です。あるレベルを超えていくには、必ず、いくつか想定できるエラーに対する対策を採らなくてはなりません。 本来、Office VBAは、仕事の片手間に作るものだから、簡単でよいのだという考え方もあります。ご自説ごもっともですが、それは、目的意識も違いますから、「そういう考え方もあるかな」と受け止めて、もしも、将来、何か別のトラブルでも発生したときには、そういえば、そんなことを言っていた人もいたなって思い出してくれればありがたいのですが。 一応、これでこちらの回答は終わらせていただきます。
お礼
こんにちは。 機嫌を損ねたわけではないですが、やはり、なぜ複雑な書き方をすることにより、信頼性が上がるのかが理解できないのです。(複雑というのは、相対的に複雑であるということです。) 仮にNameに本質的問題があるのなら、少々複雑な書き方をしたところで、その問題から逃れることはできないわけですよね。 ならばいっそのこと、Nameを一切使わずに、Nameのような独自のオブジェクトを作ってしまえというのなら、話はわかるのでが。 もし、Wendy02さんが、「そうなる条件」に熟知されていて、あの書き方でその条件を回避できるとおっしゃるのであれば、ぜひともお聞かせ願いたいのですが。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 >これでいけたのですが、なにか問題があるのでしょうか? あまり、こういうことで理屈を言っても、使用範囲にもよるし、あくまでも一般論ですが、もう少し私の説明をしておきます。 >Sub ボタン2_Click() > Range("A1").Name = "abc" >End Sub この場合の、Name オブジェクトの場合は、親オブジェクトはBook 側に入っているはずです。これを、Range オブジェクトするには、通常は、Range("abc") としなくてはいけません。名前-定義の参照範囲は、"=Sheet1!$A$1" とかなっているはずです。私が、VBAで、数式で入れるように書いたのは、単に、RangeオブジェクトのNameプロパティで設定すると、設定がどうなっているのか、見えないからなのです。 Module1 (標準モジュール)で、 Sub Test1() 'その場所を選択する場合は、 Range("abc").Select End Sub としますが、あいにく、ActiveSheet が、Sheet2 にある場合は、実行時エラーが発生します。もちろん、最初に、ActiveSheet を、Worksheets("Sheet1").Select にしておけばエラーは発生しません。ただ、なぜ、エラーになるのか、コード上では、特別なコードを入れない限りは、目では確認できなくなります。その部分だけ、標準モジュールの書法を特別扱いにしなければならなくなります。 当然、 Worksheets("Sheet2").Range("abc").Select としても、実行時エラーが発生してしまいます。 もう一つ、Sheet1の1行目で、行の挿入すると、その位置は変わっているということです。 つまり、中身は、"=Sheet1!$A$2" になっているわけです。そうすると、VBAでは、その位置を使用する前に確認しなくてはならなくなりますが、実際に、私は、そういうコードも書いた経験の中で、直接、Rangeオブジェクトではなく、文字列なので、それを、変換処理しなくてはならなくなります。 他にも、Version によってだとは思いますが、VBA上で、Namesコレクションを取得できなくなるトラブルもあると聞きます。旧バージョン(Excel2000)で、[名前]-[定義]によって、致命的エラーを発生することもあります。はっきり見えていない部分があるということは事実で、私は、[名前]-[定義]は、出来る限り、ワークシートのみに限定することにしています。 あまり、一般の方が、このようなことを気にする必要はないのだと思いますが、私自身は、VBAから、Name オブジェクトは、なかなか、制御しにくいものだという印象を持っています。
お礼
こんにちは。お返事遅くなりました。 >>Sub ボタン2_Click() >> Range("A1").Name = "abc" >>End Sub > >この場合の、Name オブジェクトの場合は、親オブジェクトはBook 側に入っているはずです。これを、Range オブジェクトするには、通常は、Range("abc") としなくてはいけません。名前-定義の参照範囲は、"=Sheet1!$A$1" とかなっているはずです。私が、VBAで、数式で入れるように書いたのは、単に、RangeオブジェクトのNameプロパティで設定すると、設定がどうなっているのか、見えないからなのです。 なぜ、わざわざ複雑な方法で設定する必要があるのかわかりません。 内部でやっているのと同じコードを書くのは、結局のところ、「車輪の再発明」でしかないのではないでしょうか。 >Sub Test1() >'その場所を選択する場合は、 > Range("abc").Select >End Sub 確かに、Selectに関しては、そういった問題があるでしょう。 でも、今回の私のプログラムではSelectは使いません、値を参照したいだけです。参照するだけなら何も問題はありません。 >もう一つ、Sheet1の1行目で、行の挿入すると、その位置は変わっているということです。 これは逆で、むしろ変わってほしいからこそ、Nameを使うのです。 そもそも絶対位置でよいのなら、最初からコード内に決め打ちで書いてしまえばそれで十分なのですから。 >つまり、中身は、"=Sheet1!$A$2" になっているわけです。そうすると、VBAでは、その位置を使用する前に確認しなくてはならなくなりますが、実際に、私は、そういうコードも書いた経験の中で、直接、Rangeオブジェクトではなく、文字列なので、それを、変換処理しなくてはならなくなります。 これこそ、「車輪の再発明」のデメリットでしょう。素直にRange("abc")で参照するなら、なにも余計な処理は要りません。 確かに見えづらい部分があるのは事実でしょうが、むやみに複雑な方法や一般的ではなさそうな方法で扱うのは、むしろバグの元ではないかと思います。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 >Nameプロパティでほぼ問題はなさそうですので、今回はこれで行こうと思います。 私の話は、あまり理解されてはいなかったようなので、少し、サンプルと説明を加えておきます。後は、ご自由にお決めください。 もちろん、ワークシートから設定する分には、どうこうありませんが、VBAでは、Name オブジェクトが使いにくいのは、Name オブジェクトの中身は、文字列の数式で、VBAからは取り扱いが面倒になることと、親オブジェクトが、Application、Workbook、 Worksheet と三つあることです。 私は、Nameオブジェクトの取り扱いは、考えるよりも、難しい面を持っているという印象がありますので、VBAは、VBAの中で一般的に扱えるものの方が便利かという話をしていたのですが……。 こんな話は余計なことだとは思いますが……。 '------------------------------ Sub TestA() Dim buf As Variant On Error Resume Next '設定されていない場合 buf = Application.Names("abc").RefersTo If Err.Number > 0 Then Names.Add "abc", "=Sheet1!$C$1" '絶対参照でないといけません End If On Error GoTo 0 Application.Goto Range("abc") End Sub '------------------------------ Sub TestB() Const MYRNG As String = "C2" Const MYSHT As String = "Sheet1" Application.Goto Worksheets(MYSHT).Range(MYRNG) End Sub '------------------------------
お礼
う~ん、設定する場合でも、 Sub ボタン2_Click() Range("A1").Name = "abc" End Sub これでいけたのですが、なにか問題があるのでしょうか?
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 #2 の回答者です。 >セルの値を参照するときに、絶対位置や相対位置で参照していると、行や列を挿入したりしたときに、位置がずれてしまいます。これを解決できないものかと。 話に具体性がないので分かりませんが、VBAでは、コードを見なければはっきりしたことがいえませんが、特定の場所をVBAで移動したら、その挿入した算定数を繰り込めば済みます。 ユーザーが挿入したりして、その都度変わるものなら、特定の文字や数式などを基点に対して、探せば済みます。もし、固定位置なら、VBAの定数を置けばよいです。 もし、これでお分かりにならないなら、具体的にコードを見せて、こうしたいというリクエストをしていただけませんか?
お礼
>ユーザーが挿入したりして、その都度変わるものなら、 ユーザーが挿入したりする場合の話でした。その場合にVBAのコードはそのままで動くようにしたかったのです。 >特定の文字や数式などを基点に対して、探せば済みます。 その、特定の文字や数式をユーザーからは容易に見たり変更できないようにしたかったのです。セルに直接、特定の文字や数式を書いた場合、ユーザーがうっかり消したり書き換えてしまったりする可能性があります。 そういった事故をなるべく防ぎたかった一方で、ユーザーがある程度ワークシートを整形して使うことも考えなければならなかったので、このような要望となりました。 Nameプロパティでほぼ問題はなさそうですので、今回はこれで行こうと思います。ありがとうございました。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 >参照するセルなのですが、場所が移動されても参照できるようにしたいのです。 「場所が移動されても」という意味が良く分かりません。 移動されるとは、「ユーザー側」からですか?もし、そうだったら、隠すことは出来ないはずです。 >ユーザーから参照も編集もできない、VBAからのみ参照、編集可能なプロパティ ・隠しシート(VeryHiddenモード)から、VBA経由で取り扱う。 ・アドインやPERSONAL.XLS 等の見えないシートの中 (シートのセルの数だけ) -終了時に保存するか聞いてきてしまうので、常に、終了時に上書きモードになる。 ・固定したものなら、VBAで、Public か、Private Const にして、モジュールに書き込みます。 ・CustomProperties こんなところだと思います。 なお、私は、Name オブジェクトの Visible =False は、失敗するとVBAからは制御できなくなるという話を聞いたので、やったことがありません。 プロパティのID等なら、クラス-インスタンスで設ければよいのですが、定数以外は、書き換えは可能ですが、保存はどこかに書き込まない限りはできません。 基本的に、どこまで、ユーザーに見せないか、ということになるのではないでしょうか? 通常、私などは、CustomProperties を使います。それは、分かっているユーザーから見えます。それ以上の秘匿性の高いものや保存性のあるものが、ないとは言いませんが、話のレベルが違いますからやめておきます。Excelで、そんなに神経質にならければならないものに出会ったことがありません。どこかで、妥協したほうがよいですね。
お礼
ありがとうございます。 >・隠しシート(VeryHiddenモード)から、VBA経由で取り扱う。 >・アドインやPERSONAL.XLS 等の見えないシートの中 (シートのセルの数だけ) >-終了時に保存するか聞いてきてしまうので、常に、終了時に上書きモードになる。 >・固定したものなら、VBAで、Public か、Private Const にして、モジュールに書き込みます。 >・CustomProperties 申し訳ありません。セルの値そのものを隠したいわけではないのです。 セルの値を参照するときに、絶対位置や相対位置で参照していると、行や列を挿入したりしたときに、位置がずれてしまいます。これを解決できないものかと。 例として、コメントを挙げたわけですが、あくまでも参照したいのはセルの値であって、コメントはラベルとして使いたいのです。 ですが、コメントの場合、ユーザーから書き換え可能ですし、ポップアップで妙な文字列が出てしまうのも不気味ですので、なにか別のプロパティがないかと質問に到ったわけです。 曖昧な質問で申し訳ありませんでした。
お礼
ありがとうございます。 IDが.xlsに保存されないのは、投稿後気が付きました。まさか保存されないとは盲点でした。 >普通は「名前定義」を利用して、その名前でセル参照を行います VBAからだと、Nameプロパティですね。 動作を調べてみましたが、ほぼ希望の動作といえるものですね。ありがとうございます。 これでユーザーから参照できなければ完璧なのですが・・・難しそうですね。 まあ、うっかりと変更、削除してしまうものでもなさそうなので、運用で逃げられそうではあります。ありがとうございました。