[[20210712220604]] 『Countに関する実行時エラーについて』(kenichi) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『Countに関する実行時エラーについて』(kenichi)

シート名:「T_解除申込」
テーブル名:「T_解除申込」のときの「T_解除申込」のレコード数を求める場合

sub test1()
 Sheets("T_解除申込").ListObjects("T_解除申込").ListRows.Count
end sub

と記載すると、エラーになります。
実行時エラー438
オブジェクトは、このプロパティまたはメソッドをサポートしていません。

sub test2()
 Dim m as Long

  m = Sheets("T_解除申込").ListObjects("T_解除申込").ListRows.Count
end sub

あるいは

sub test3()

    With Sheets("T_解除申込").ListObjects("T_解除申込")
        Debug.Print .ListRows.Count
    End With
end sub

と記載するとエラーになりません。

なぜ、test1の場合、エラーになるのか、教えて頂けないでしょうか。

< 使用 Excel:Excel2019、使用 OS:Windows10 >


 もうちょっとわかりやすい例で。
    Sub test1()
       ActiveSheet.Rows.Count   ' アクティブシートの行数を.....
    End Sub
    Sub test2()
       c = ActiveSheet.Rows.Count  ' アクティブシートの行数を変数Cに代入する
    End Sub
    Sub test3()
       Debug.Print ActiveSheet.Rows.Count ' アクティブシートの行数をイミディエイトウインドウに出力する
    End Sub

 自然言語的な言い方をすると、「□□を○○する」の動詞部分「○○する」がないから。
 VBAが何をしていいか解らないのでエラー
 ステートメントとして完結してません
(´・ω・`) 2021/07/12(月) 22:44

こうやっているようなもんだもの。
↓これのどこがいけないか解りますか?

Sub abc()

   Range("A1:A5").Rows.Count
End Sub
(ピッピとサリー) 2021/07/12(月) 22:45

 test2とtest3は、行数をmに代入したり、イミディエイトウィンドウに出力したりしていますので
 何も問題は起きません。

 test1は単に行数を調べただけですよね? それを何にも利用していない。
 無意味なことをやっているステートメントです。

 でも、無意味だからと言って「オブジェクトは、このプロパティまたはメソッドをサポートしていません。」は
 ひどいじゃないかとは言えますね。

 オブジェクトは、Sheets("T_解除申込").ListObjects("T_解除申込").ListRows であり、
 そのプロパティにCountは有るんだから、エラーの文言は変であることは確か。
 もう少しましなエラー文言はなかったものですかねぇ。。

 でも、エラーにならないとして、どうなって欲しいんですか?(私はそれがすごく知りたい)
 納得行く理由があればMicrosoftに文句が言えるかも知れないです。

(半平太) 2021/07/12(月) 22:51


 あんまり本題とは関係ないですけど^^;

    Sub test()
        [A10].Value = 1
        [A10].Value = Empty
        Debug.Print Cells.SpecialCells(xlCellTypeLastCell).Address
        ActiveSheet.UsedRange '←この呼び出しっ放しはよく使いますね([最後のセル]位置のリセット用)
        Debug.Print Cells.SpecialCells(xlCellTypeLastCell).Address
    End Sub

 左辺なくてもエラーにならないし。

(白茶) 2021/07/12(月) 23:44


 Rangeで幾つか試してみました。

    Sub test()
        With Cells(2, 2)
            .CurrentRegion      'エラーなし
            .Next               'エラーなし
            .Previous           'エラーなし
            .Interior           '1004 RangeクラスのInteriorメソッドが失敗しました
            .HasFormula         '1004 RangeクラスのHasFormulaメソッドが失敗しました
            .Font               '1004 RangeクラスのFontメソッドが失敗しました
            .Font.Bold          '1004 FontクラスのBoldメソッドが失敗しました (←クラスがRangeからFontに変わった)
        End With
    End Sub

 そもそもInteriorやHasFormulaは「メソッド」なのか? なんて突っ込みは置いといて^^;

 最初はプロパティに対するGetなのかSet/Letなのか確定しない構文だとエラーなのか? とも思いましたが、
 エラーの出ないプロパティがある以上そう単純な話ではなさそう。
 (上記の3つはエラー出さなかったけど、他の読み取り専用プロパティでも大抵失敗しますね)

 「文法的に不完全だから」という理由なら、
 じゃあCurrentRegionやNextはなぜエラーじゃないの? という疑問が生じますので
 こうなってくると、各プロパティの「作り」にも寄ってくるのかな?  という気もしてきました。

 あらかじめ用意されたものの挙動なので、こりゃもう分かんないですね〜

(白茶) 2021/07/13(火) 02:36


  皆さんの議論、参考にさせていただいています。ありがとうございます。
  (1) 
    白茶さんのテストを私も確認してみました。
    Excel2010環境でもCells(2,2)に関しては同様の結果でした。

    ただし、Range("B2")でもやってみると、面妖なことに、結果が違いました。
    すべてコンパイルエラーになるようです。
    With Range("B2")
        .CurrentRegion  'エラー(コンパイルエラー:プロパティの使い方が不正です)
        .Next           'エラー(コンパイルエラー:プロパティの使い方が不正です)
        .Previous       'エラー(コンパイルエラー:プロパティの使い方が不正です)
        .Interior       'エラー(コンパイルエラー:プロパティの使い方が不正です)
        .HasFormula     'エラー(コンパイルエラー:プロパティの使い方が不正です)
        .Font           'エラー(コンパイルエラー:プロパティの使い方が不正です)
        .Font.Bold      'Boldがハイライトされ、同上のエラーメッセージ。
    End With

  (2) 
    なお、UsedRangeに関してですが、
    With Worksheets("Sheet1")
        .UsedRange      'エラーなし
    End With
    となりますが、不思議なことに、こう書くとエラーになりますね。
    With Sheet1
        .UsedRange  'エラー(コンパイルエラー:プロパティの使い方が不正です)
    End With

    ・前者は、最終行などの更新機能を盛り込んだため、エラーにできず
      今まで存置されているものと想像されます。
    ・後者は、整合性がないですね。ラッパークラスのはずなのに。不思議です。

  基本的には、皆さんご指摘のとおり、
  変数に入れたり、他のメソッドや関数の引数にしないような使い方は不可と
  考えてよいと思いますが、それでは割り切れない事象も残っているようです。
  まあ、これだけ大きなアプリケーションで、色々建て増しもしてきていますから、
  そうしたこともあるのではないかと思っています。
  原因はわかりませんが、そういうものとして使うほかないと思います。
(γ) 2021/07/13(火) 07:10

 >コンパイルエラー:プロパティの使い方が不正です
 お〜。 まさに構文エラーですね。

    Sub test()
        Dim c As Range
        c.CurrentRegion
    End Sub

    Sub test()
        Dim s As Worksheet
        s.UsedRange
    End Sub
 確かにどっちも同じエラーです。

 オブジェクトブラウザで確認すると、
 Class Application
     Property ActiveSheet As Object ←[Class Worksheet]未確定(結果的に構文エラーを免れた?)
     Property Worksheets As Sheets
                          ↓
                        Class Sheets
                            Property Item(Index) As Object ←[Class Worksheet]未確定(結果的に構文エラーを免れた?)

     Property Range(Cell1, [Cell2]) As Range ←[Class Range]確定(構文エラーに引っ掛かった)
     Property Cells As Range ←あれ? ここも[Class Range]確定してるじゃん。

 はは〜...
 なんか事前バインディングと実行時バインディングの関係にちょっと似てなくもないですね。
 構文エラー有無がインテリセンスが働く状況か否かとリンクしてる様な気がします。

 Cells.Worksheet.UsedRange 'プロパティの使い方が不正です
 Cells.Parent.UsedRange    'エラーなし
             ↑インテリセンス効かない(Property Parent As Objectだから?)

 Cells. ←インテリセンスが働く
 Cells(1, 1). ←インテリセンス効かない(ってことは[Class Range]未確定?)

 Sheets("T_解除申込").ListObjects("T_解除申込").ListRows.Count
                     ↑インテリセンス効かない(から、とりあえずコンパイルエラーではない)
 Sheet1.ListObjects(1).ListRows.Count ←インテリセンスが働く(けどコンパイルエラー)

(白茶) 2021/07/13(火) 11:37


 オブジェクトのメンバーの書き方でも差が出る様です。

 Sub test10()
     Dim cls As Class1

     Set cls = New Class1     
     cls.b = 99

     Debug.Print cls.a '99
     Debug.Print cls.b '99
     Debug.Print cls.c '99

     cls.a 'コンパイルエラー。変数でなく、プロシージャを指定してください。
     cls.b 'コンパイルエラー。プロパティの使い方が不正です
     cls.c 'エラーなし

     'インテリセンスが効かない場合を追試
     Dim cObj As Object
     Set cObj = cls

     cObj.a 'オブジェクトは、このプロパティまたはメソッドをサポートしていません。
     cObj.b '引数の数が一致していません。または不正なプロパティを指定しています。
     cObj.c 'エラーなし

 End Sub

 ※インテリセンスが効かない場合を追加しました。12:52

(半平太) 2021/07/13(火) 12:35


 半平太さん、教えてください。

 上記Class1内での各プロパティって、どんな書き方ですか?

 aはClass1のPublic変数
 bはClass1のPublic Property
                    ...で定義してやる事で再現できたんですけど、
                       cがちょっと分かんなくて^^;

(白茶) 2021/07/13(火) 15:53


 半平太さんのおそらくClass1はこうでしょう

    Public a As Long

    Public Property Get b() As Long
      b = a
    End Property

    Public Property Let b(ByVal vNewValue As Long)
      a = vNewValue
    End Property

    Public Function c()
      c = a
    End Function
(´・ω・`) 2021/07/13(火) 16:02

 済みません。追試を加えた時、Class1のクラスを消しちゃいました。m(__)m

 [Class1]------------
 Public a As Long

 Property Let b(z As Long)
     a = z
 End Property

 Property Get b() As Long
     b = a
 End Property

 Function c() As Long
     c = a
 End Function

 cはファンクションプロシージャです。

 これは普通プロパティとは呼ばないですが、同種と思っています。
 マイクロソフトも、厳密にプロパティとメソッドを区別してないと思っています。

 Interiorはメソッドじゃないので、こんなエラー文言はそもそもおかしいと言わなければならないです。
  ↓
 >  .Interior           '1004 RangeクラスのInteriorメソッドが失敗しました

(半平太) 2021/07/13(火) 16:14


 あー、ナルホド。 そゆことですね。
 お二人ともありがとうございました。

(白茶) 2021/07/13(火) 16:21


皆様、返信ありがとうございました!
vbaの理解が深まりました。
全てが原則通りに成り立つ訳ではないこともわかり
気持ちも楽になりました。
(kenichi) 2021/07/13(火) 19:08

 今回はどんな原則だったんですか? 

 「まともなプログラマーは、無意味なステートメントを書くべきではない」と言うのが
 原則の一つと思っているんですが、これが成り立たなかった訳じゃないですね?

(半平太) 2021/07/13(火) 20:09


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.