Excel (一般機能)

Excelの一般機能に関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Home : Excel 2016)
セルのEmpty値について
投稿日時: 18/10/12 15:53:51
投稿者: はじめて

お世話になります。
セルがEmpty値となるため正常に動作しません。調べましたがわかりません。ご教授いただけませんか。
Dim 歌CNT As Integer
    歌CNT = 1 としています。
  
 
        Case 5, 8, 11, 14, 17, 20
          If 歌CNT = 歌loop Then   **この部分の歌cntには数字が入っている。
             七夕さま
             歌位置
         End If
       
    End Select
  
    歌loop = 歌loop + 1
    秒待ち
    秒待ち
    
    cnt = 1
    i = 19
       
  Loop
 
 End Sub
 
 Sub 歌位置()
 
    If 歌CNT = 1 Then ’**** 歌cntには数字が入ってこず「Empty値」となるため正常に動作しない
 
             歌CNT = 5
    End If
        If 歌CNT = 8 Then
             歌CNT = 9
    End If
        If 歌CNT = 12 Then
             歌CNT = 13
    End If
        If 歌CNT = 16 Then
             歌CNT = 17
    End If
End Sub

回答
投稿日時: 18/10/12 16:10:39
投稿者: sk

引用:
Dim 歌CNT As Integer

この変数をどこで宣言されているのでしょうか。
 
引用:
Sub 歌位置()
  
    If 歌CNT = 1 Then ’**** 歌cntには数字が入ってこず「Empty値」となるため正常に動作しない

・モジュールレベルに Option Explicit ステートメントが宣言されていない。
 
・変数[歌CNT]がモジュールレベルではなく、
 プロシージャ[歌位置]とは別のプロシージャの
 プロシージャレベルで宣言されている。
 
引用:
セルがEmpty値となるため正常に動作しません。

「セル」ではなく「変数」ですよね。

投稿日時: 18/10/12 16:15:19
投稿者: はじめて

sk さん
早速ありがとうございます。
 
歌CNT は標準モジュールで宣言しています。

投稿日時: 18/10/12 16:20:53
投稿者: はじめて

 sk さん
以下をトップに代入し処理しましたところ、「コンパイルエラー」及び「変数が定義されていません」とのメッセージが出ました。
 
Option Explicit

回答
投稿日時: 18/10/12 16:33:16
投稿者: WinArrow
投稿者のウェブサイトに移動

>歌CNT は標準モジュールで宣言しています。
 
標準モジュールの名前と
変数定義の場所と定義内容を掲示してみましょう。
 
それから、問題のコードは、どこ(モジュール名)に記述していますか?

回答
投稿日時: 18/10/12 16:37:14
投稿者: WinArrow
投稿者のウェブサイトに移動

回答した後で気がついたけど・・・・
 
このスレは版違いですね?
「VBAの版」ですね・・・

投稿日時: 18/10/12 16:47:16
投稿者: はじめて

WinArrow さん
 
ありがとうございます。
標準モジュールのModule1に記載しています。
Sub 歌位置() はサブルーティンでこの中の変数に数字が入ってきません。
 
If 歌CNT = 歌loop Then   **この部分の歌cntには数字が入っている。
 ここには数字が入っているのにと思っています。
よろしくお願いします。

回答
投稿日時: 18/10/12 16:48:30
投稿者: WinArrow
投稿者のウェブサイトに移動

 
どうでもよいが
   
歌位置プロシジャの中の
   If 歌CNT = 1 Then
   If 歌CNT = 12 Then
   If 歌CNT = 16 Then
     
この条件には疑問があります。
 存在していてもよいが、条件に当てはまることがない
条件が成立するのは
>If 歌CNT = 8 Then
だけでは?
 
 

投稿日時: 18/10/12 17:12:44
投稿者: はじめて

WinArrow さん
 
サブルーチンに入ってきて、戻る時にはどの歌CNTをもってメインに帰るかということを考えています。
 歌CNT = 5 、 歌CNT = 9 、 歌CNT = 13 、 歌CNT = 17 のいずれかをもって戻りたいのです。

回答
投稿日時: 18/10/12 17:23:52
投稿者: sk

引用:
歌CNT は標準モジュールで宣言しています。

標準モジュールのどこに宣言されたかが
問題なのですが。
 
なお、1 つのプロシージャにおいて参照出来るのは、
次のような変数です。
 
・そのプロシージャの内部(プロシージャレベル)で
 宣言された変数。
 
・そのプロシージャが定義されているモジュールの
 モジュールレベル(モジュールの先頭行から、
 最初のプロシージャが定義されるまでの間の行)で
 宣言された変数。
 
・他のモジュールのモジュールレベルで宣言された変数のうち、
 参照範囲(スコープ)が Public である変数。
 (モジュールレベルの変数のスコープが Private である場合、
  その変数を宣言したモジュール内でしか参照出来ない)
 
例えば、1 つのモジュール内に 2 つのプロシージャが
定義されているとして、それぞれのプロシージャにおいて
同じ名前の変数が宣言されていた場合、それらの変数は
それぞれのプロシージャ固有の変数として扱われます。
 
(標準モジュール)
------------------------------------------------------------
Option Explicit
 
Dim x As Integer 'この変数はこのモジュール内でのみ参照可
 
Sub test1()
 
    Debug.Print "test1:"
 
    Dim i As Integer 'この変数は test1 内部でのみ参照可
 
    x = 1
    i = 1
     
    Debug.Print "x = " & x
    Debug.Print "test1 の i = " & i
 
    Call test2
 
    Debug.Print "x = " & x
    Debug.Print "test1 の i = " & i
 
End Sub
 
Sub test2()
 
    Debug.Print "test2:"
 
    Dim i As Integer 'この変数は test2 内部でのみ参照可
 
    Debug.Print "x = " & x
    Debug.Print "test2 の i = " & i
 
    Debug.Print "各変数に値を代入します"
     
    x = 2
    i = 2
 
    Debug.Print "x = " & x
    Debug.Print "test2 の i = " & i
 
End Sub
------------------------------------------------------------
 
なお、更に test1 または test2 のプロシージャレベルに
変数 x を宣言した場合は、モジュールレベルで宣言された x より
自身のプロシージャレベルで宣言された x の方を優先して参照します。
 
引用:
トップに代入し処理しましたところ、「コンパイルエラー」及び
「変数が定義されていません」とのメッセージが出ました。

・モジュールレベルの冒頭に Option Explicit ステートメントを
 記述されていない場合、どの変数/定数/メンバ/キーワードとも
 解釈出来ない単語は、暗黙的にプロシージャレベルの変数と見なされ、
 そのデータ型は Variant 型として扱われる。
 (そして Variant 型の初期値は Empty である)
 
・モジュールレベルの冒頭に Option Explicit ステートメントを
 記述した場合、そのモジュール内においては必ず変数の宣言が
 強制される。
 (もし宣言されていない変数が存在した場合は
 コンパイルエラーとして処理される)
 
今回の場合は、以下の要因が全て揃っているためでしょう。
 
・プロシージャ[歌位置]のプロシージャレベルに
 [歌CNT]という名前の変数が明示的に宣言されていない。
 
・プロシージャ[歌位置]が定義されているモジュールの
 モジュールレベルにおいても[歌CNT]という名前の変数が
 宣言されていない。
 
・他のどのモジュールのモジュールレベルにおいても、
 [歌CNT]という名前の Public な変数は宣言されてない。
 
引用:
Sub 歌位置()
  
    If 歌CNT = 1 Then

結果、ここでの[歌CNT]は「プロシージャ[歌位置]でのみ
有効な Variant 型の変数」として解釈されることになります。

投稿日時: 18/10/12 17:27:03
投稿者: はじめて

変数が Empty 値 である場合とは、その変数が初期化されていない場合(変数宣言のみで値が代入されていない状態)または、その変数に「Empty」を直接代入した場合のみです。
 
Empty 値 とは、バリアント型の変数が格納できる特殊な値で、数値としては「0」、文字としては長さ「0」の文字列として評価されます。
 
というのが掲載されてたWEBにありましたが、理解できません。

回答
投稿日時: 18/10/12 17:36:43
投稿者: sk

引用:
Empty 値 とは、バリアント型の変数が格納できる特殊な値で、
数値としては「0」、文字としては長さ「0」の文字列として評価されます。
  
というのが掲載されてたWEBにありましたが、理解できません。

「 Empty 値とはどういうものか」ということは、
今は問題ではありません。
 
・変数の宣言を強制しているか/していないか。
 
・変数が明示的に宣言されているか/されていないか。
 
・それぞれの変数はどのモジュールのどのレベルで宣言されているか。
 
・それぞれの変数のスコープはどの範囲まで有効か。
 
以上の点を理解した上で、それぞれの変数の宣言を
適切に行なえているかどうかの問題です。

回答
投稿日時: 18/10/12 17:44:37
投稿者: WinArrow
投稿者のウェブサイトに移動

はじめて さんの引用:
WinArrow さん
 
ありがとうございます。
標準モジュールのModule1に記載しています。
Sub 歌位置() はサブルーティンでこの中の変数に数字が入ってきません。
 
If 歌CNT = 歌loop Then   **この部分の歌cntには数字が入っている。
 ここには数字が入っているのにと思っています。
よろしくお願いします。

 
複数のプロシジャで使用する(参照を含む)変数は、
プロシジャ内ではなく、モジュールレベルで定義します。
 
プロシジャ内で定義した変数は、プロシジャ内でのみ有効です。
 
「変数のスコープ」を勉強してみてください。

投稿日時: 18/10/12 17:57:22
投稿者: はじめて

sk さん、WinArrow さん
 
詳細なご教示に感謝申します。ありがとうございました。
本日の教訓を生かし、組み立てなおしたいと思っています。
再度お礼申します。