過去ログ

                                Page     155
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   通常モードに戻る  ┃  INDEX  ┃  ≪前へ  │  次へ≫   
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 ▼Public宣言について  haru 02/10/1(火) 10:21
   ┣Re:Public宣言について  つん 02/10/1(火) 10:51
   ┃  ┗Re:Public宣言について  haru 02/10/1(火) 13:11
   ┃     ┗Re:Public宣言について  つん 02/10/1(火) 13:36
   ┃        ┗Re:Public宣言について  こうちゃん 02/10/1(火) 14:33
   ┃           ┣Re:Public宣言について  つん 02/10/1(火) 16:19
   ┃           ┗Re:Public宣言について  haru 02/10/2(水) 9:10
   ┃              ┗Re:Public宣言について  つん 02/10/2(水) 9:48
   ┃                 ┗Re:Public宣言について  こうちゃん 02/10/2(水) 11:01
   ┃                    ┗Re:Public宣言について  haru 02/10/2(水) 11:21
   ┗Re:Public宣言について  ichinose 02/10/1(火) 11:01
      ┗Re:Public宣言について  haru 02/10/1(火) 13:21
         ┗Re:Public宣言について  ichinose 02/10/1(火) 17:08

 ───────────────────────────────────────
 ■題名 : Public宣言について
 ■名前 : haru
 ■日付 : 02/10/1(火) 10:21
 -------------------------------------------------------------------------
   Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)

 ここから、モジュールのサブルーチンをcallしたとき、
 シートとモジュールの両方で、Public宣言しても、データの値が
保持されません。
 どうすれば保持できますか?
 よろしくお願いします。
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : つん <honey@sweetparty.ne.jp>  ■日付 : 02/10/1(火) 10:51  -------------------------------------------------------------------------
   おはようございます。

>Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
>
> ここから、モジュールのサブルーチンをcallしたとき、
> シートとモジュールの両方で、Public宣言しても、データの値が
>保持されません。
> どうすれば保持できますか?
> よろしくお願いします。

両方に同じ変数をPublicで宣言された・・ということでしょうか?
パブリック変数は、標準モジュールの宣言部分で宣言します。

*標準モジュール*******************
Public A As Long

Sub Test()
  A = 10
End Sub

*ワークシート********************
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  Call Test
  MsgBox "A = " & A
End Sub

**********************************

こんな感じで、ちゃんと「A=10」のメッセージボックスが出ますけど・・・
こういうことじゃなかった?
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : haru  ■日付 : 02/10/1(火) 13:11  -------------------------------------------------------------------------
   ▼つん さん:
 こんにちは。ありがとうございます。
 うまくいきました。

>両方に同じ変数をPublicで宣言された・・ということでしょうか?
 そうです。
>パブリック変数は、標準モジュールの宣言部分で宣言します。
 念のためにそうしました。それがいけなかったようです。
 でも、以下のようにしても「A=10」のメッセージボックスが出ます。

>*標準モジュール*******************
>Public A As Long

>Sub Test()
>  A = 10
>End Sub

>*ワークシート********************
Public A As Long
>Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
>  Call Test
>  MsgBox "A = " & A
>End Sub

>**********************************
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : つん <honey@sweetparty.ne.jp>  ■日付 : 02/10/1(火) 13:36  -------------------------------------------------------------------------
   >
>>両方に同じ変数をPublicで宣言された・・ということでしょうか?
> そうです。
>>パブリック変数は、標準モジュールの宣言部分で宣言します。
> 念のためにそうしました。それがいけなかったようです。

同じ名前で同じように宣言しても、それは別物になるんじゃないかと思います。
標準モジュール以外で、パブリックで宣言しても、その変数は、そのモジュール内だけでのみ参照可能になります。なので、

> でも、以下のようにしても「A=10」のメッセージボックスが出ます。
>
>>*標準モジュール*******************
>>Public A As Long
>
>>Sub Test()
>>  A = 10
>>End Sub
>
>>*ワークシート********************
>Public A As Long
>>Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
>>  Call Test
>>  MsgBox "A = " & A
>>End Sub
>
>>**********************************

ここでメッセージボックスで出てくる「A」は標準モジュールで宣言した「A」になると思います。

ここから私が質問させていただきます。(すんません、混乱してきたっ(>_<))

*ワークシート********************
Public A As Long

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  Call Test
  Call test2
  MsgBox "A = " & A
End Sub

Sub test2()
  A = 20
End Sub
*******************************

こうした場合、メッセージボックスには「A=20」が出るのですが、(test2を後からコールしてるから当然ですが)
この場合の、「A」は、ワークシートモジュール内で宣言した「A」なんでしょうか?
標準モジュール内で宣言した「A」なんでしょうか?
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : こうちゃん <nakajima19@hotmail.com>  ■日付 : 02/10/1(火) 14:33  -------------------------------------------------------------------------
   みなさん、こんにちは

横レス失礼します。

>ここから私が質問させていただきます。(すんません、混乱してきたっ(>_<))
>
>*ワークシート********************
>Public A As Long
>
>Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
>  Call Test
>  Call test2
>  MsgBox "A = " & A
>End Sub
>
>Sub test2()
>  A = 20
>End Sub
>*******************************
>
>こうした場合、メッセージボックスには「A=20」が出るのですが、(test2を後からコールしてるから当然ですが)
>この場合の、「A」は、ワークシートモジュール内で宣言した「A」なんでしょうか?
>標準モジュール内で宣言した「A」なんでしょうか?

そうです、ワークシートモジュール内で宣言した「A」を表示しています。
モジュールレベル(シートモジュール含む)で宣言したパブリック変数はグローバルな適用範囲を持ちますが、同じ名前で宣言した変数は、別のグローバル変数として有効になります。
その場合の区別はモジュール名を修飾して区別するのですが、修飾子がない場合は自モジュールの変数が自動的に検索されますので、この例の場合は、シートモジュールで宣言した「A」が参照されるのです。

以下の例でシートモジュールのtest1を実行してみてください。

test1のMsgBox "A = " & A
では、自モジュールのAを参照しますので値は20です。

Call test3 で呼ばれた標準モジュールの
  MsgBox "A = " & A
では、標準モジュールの「A」を参照しますので値は0です。

Call test4 で呼ばれた標準モジュールの
  MsgBox "A = " & sheet1.A
では、シートモジュールの「A」を参照しますので値は20です。


*標準モジュール********************
Public A As Long

Public Sub test3()
  MsgBox "A = " & A
End Sub

Public Sub test4()
  MsgBox "A = " & sheet1.A
End Sub

*ワークシート********************
Public A As Long

Private Sub test1()
  Call test2
  MsgBox "A = " & A
  Call test3
  Call test4
End Sub

Sub test2()
  A = 20
End Sub
*******************************

#宣言が重複するとバグのもとになりますし、デバグも難しくなりますから気をつけましょうね^^;
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : つん <honey@sweetparty.ne.jp>  ■日付 : 02/10/1(火) 16:19  -------------------------------------------------------------------------
   こうちゃん さん、こんにちはー

レスありがとうございました。

>そうです、ワークシートモジュール内で宣言した「A」を表示しています。
>モジュールレベル(シートモジュール含む)で宣言したパブリック変数はグローバルな適用範囲を持ちますが、同じ名前で宣言した変数は、別のグローバル変数として有効になります。
>その場合の区別はモジュール名を修飾して区別するのですが、修飾子がない場合は自モジュールの変数が自動的に検索されますので、この例の場合は、シートモジュールで宣言した「A」が参照されるのです。

わかりました。私も、自モジュールの変数が優先(?)されるのじゃないかな?
って思ったのですが、いまいち確証がもてませんでした。

サンプルコートもよーわかりました(^o^)ノ

>#宣言が重複するとバグのもとになりますし、デバグも難しくなりますから気をつけましょうね^^;

ですねー。私も、変数名は重複しないようにしています。
グローバル変数とローカル変数の区別がつくようにもしてるけど・・・でも、変数名って悩みますねー
ちょこっとしたコードなら、変数も少ないし簡単だけど、大きくなってくると、変数も多くなってきて困ります。
しまいにゃ、連番つけたりして・・・あとで訳わからんくなるので、あまり好きじゃないんですけどね、連番って。
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : haru  ■日付 : 02/10/2(水) 9:10  -------------------------------------------------------------------------
   >その場合の区別はモジュール名を修飾して区別するのですが、修飾子がない場合は自モジュールの変数が自動的に検索されますので、この例の場合は、シートモジュールで宣言した「A」が参照されるのです。
 敢えて使おうというわけではないんですが、変数を修飾する方法
がわかりません。
 ご存じの方、よろしくお願いします。
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : つん <honey@sweetparty.ne.jp>  ■日付 : 02/10/2(水) 9:48  -------------------------------------------------------------------------
   > 敢えて使おうというわけではないんですが、変数を修飾する方法
>がわかりません。

こうちゃんさんのコードにある、

MsgBox "A = " & sheet1.A

の、「sheet1.A」の部分が修飾されて方法だと思います。
ですよね?こうちゃんさん!
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : こうちゃん <nakajima19@hotmail.com>  ■日付 : 02/10/2(水) 11:01  -------------------------------------------------------------------------
   haruさん、つんさん、こんにちは

>> 敢えて使おうというわけではないんですが、変数を修飾する方法
>>がわかりません。
>
>こうちゃんさんのコードにある、
>
>MsgBox "A = " & sheet1.A
>
>の、「sheet1.A」の部分が修飾されて方法だと思います。
>ですよね?こうちゃんさん!

です。
変数の競合を避けるために、変数を修飾する場合は、

[プロジェクト名.[モジュール名.]]変数名

の形で修飾します。

ex:プロジェクト名を含む
標準モジュール:Book1.Module1.A
シートモジュール:Book1.Sheet1.A

ex:モジュール名を含む
標準モジュール:Module1.A
シートモジュール:Sheet1.A

#HELPでPublicを検索して、「名前の二重定義の回避」や「適用範囲と参照可能範囲の概要」を参照してみてください。
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : haru  ■日付 : 02/10/2(水) 11:21  -------------------------------------------------------------------------
   ▼こうちゃん さん、つんさん、こんにちは

>変数の競合を避けるために、変数を修飾する場合は、
>[プロジェクト名.[モジュール名.]]変数名
>の形で修飾します。
 わかりました。ありがとうございます。

>#HELPでPublicを検索して、「名前の二重定義の回避」や「適用範囲と参照可能範囲の概要」を参照してみてください。
 これは、エクセル2000ですよね。こちらで発見できました。
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : ichinose  ■日付 : 02/10/1(火) 11:01  -------------------------------------------------------------------------
   ▼haru さん:
こんにちは。
回答ではありませんが、私も非常に興味のあるご質問だったので、投稿しました。
具体的にどこで保持されないのかコードを示す事ができませんか?
変数の値の保持が信用できないという話は前前から聞いてはいましたが、
実際に経験したことがありません。
対処法として、セルにデータを移しておくという解決方法も目にした事がありますが、
セルに保存できないオブジェクト変数などの場合は、どうするのだろうと思っていました。隠しフォームを作ってとか・・も聞いた事がありますが・・・。

「変数の値が保持されない」を私のPCでも再現させてみたいので、
よろしかったら、教えて下さい。

>Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Excel.Range, Cancel As Boolean)
>
> ここから、モジュールのサブルーチンをcallしたとき、
> シートとモジュールの両方で、Public宣言しても、データの値が
>保持されません。
> どうすれば保持できますか?
> よろしくお願いします。
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : haru  ■日付 : 02/10/1(火) 13:21  -------------------------------------------------------------------------
   ▼ichinose さん:
 こんにちは。

>「変数の値が保持されない」を私のPCでも再現させてみたいので、
>よろしかったら、教えて下さい。

'*ワークシート********************
Public A As Long, b$

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    Call Test
    MsgBox "A = " & A
    MsgBox "b$ = " & b$
End Sub


'*標準モジュール*******************
Public A As Long, b$

Sub Test()
  A = 10
  b$ = 1
End Sub

 とすると、手許のPCでは、b$は表示されません。
 (私がお答するのも何なんですが。)
 ───────────────────────────────────────  ■題名 : Re:Public宣言について  ■名前 : ichinose  ■日付 : 02/10/1(火) 17:08  -------------------------------------------------------------------------
   ▼haru さん:
みなさん、こんにちは。
私、大きな勘違いをしていたようですね。
既に解決したようなので、よかっです。
理解力のなさを露呈してしまいました。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    通常モードに戻る  ┃  INDEX  ┃  ≪前へ  │  次へ≫    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━                                 Page 155