[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/09/15(Thu) 18:33
投稿者名:ダンボ
URL :
タイトル:
VBAで「型が一致しません」
EXCEL2002のVBAです。txt1はテキストボックスです。これを実行してtxt1_AfterUpdate内で
DateCheckを呼び出したところでエラー13「型が一致しません」と言われます。なんで?

Private Sub txt1_AfterUpdate()
txt1.Text = Format(txt1.Text, "Long Date")
DateCheck txt1    <-ここでエラー
End Sub

Private Sub txt2_AfterUpdate()
txt2.Text = Format(txt2.Text, "Long Date")
DateCheck txt2
End Sub

Private Sub DateCheck(TBOX As TextBox)
If Not IsDate(TBOX.Text) Then MsgBox ("正しい日付を入力してください")
'TBOX.Select
End Sub

もひとつ。不正日付のテキストボックスの文字を反転させたいのですが、SelStart,SelLengthが
無いので、どうしたらよいでしょうか?

投稿時間:2005/09/15(Thu) 20:38
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: VBAで「型が一致しません」
> Private Sub DateCheck(TBOX As TextBox)
>  If Not IsDate(TBOX.Text) Then MsgBox ("正しい日付を入力してください")
>  'TBOX.Select
> End Sub

下記のようにObject型に変更して見てください。

Private Sub DateCheck(TBOX As Object)
If Not IsDate(TBOX.Text) Then MsgBox ("正しい日付を入力してください")
'TBOX.Select
End Sub

>
> もひとつ。不正日付のテキストボックスの文字を反転させたいのですが、SelStart,SelLengthが
> 無いので、どうしたらよいでしょうか?

ありますよ。自動メンバ表示で出てきますよ。
    TextBox2.SelStart
    TextBox2.SelLength
 

投稿時間:2005/09/16(Fri) 11:48
投稿者名:ダンボ
URL :
タイトル:
【解決】VBAで「型が一致しません」
花ちゃんさん、どうもありがとうございました。
下記コードで望みどおりの仕様になりました。助かりました。ちょっと一人では解決できなかった。

> Object型に変更して見てください。
う〜ん、納得できない。VBAのバグと言われてもしょうがないのでは?
> ありますよ。自動メンバ表示で出てきますよ。
Sub DateCheck(TBOX As TextBox)の編集時には出てこない。
Sub DateCheck(TBOX As Object)の編集時でも出てこない(こちらは当然?)。
> 文字を反転させたい
それでも反転しなかったのでプロパティリストを再確認すると"HideSelection"を発見。
ああ、VBAとVB6はちょっとずつ違いますね。

Private Sub cmdOK_Click()
If DateCheck(txt1) Then Exit Sub
If DateCheck(txt2) Then Exit Sub
If CDate(txt1.Text) > CDate(txt2.Text) Then
   MsgBox ("開始日>終了日")
   Exit Sub
End If
Me.Hide
End Sub

Private Sub txt1_AfterUpdate()
txt1.Text = Format(txt1.Text, "Long Date")
DateCheck txt1
End Sub

Private Sub txt2_AfterUpdate()
txt2.Text = Format(txt2.Text, "Long Date")
DateCheck txt2
End Sub

Private Function DateCheck(TBOX As Object) As Boolean
If Not IsDate(TBOX.Text) Then
   TBOX.SelStart = 0
   TBOX.SelLength = Len(TBOX.Text)
   TBOX.SetFocus
   MsgBox ("正しい日付を入力してください")
   DateCheck = True
Else
   DateCheck = False
End If
End Function
 

投稿時間:2005/09/16(Fri) 12:27
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: 【発見】VBAで「型が一致しません」
> > Object型に変更して見てください。
> う〜ん、納得できない。VBAのバグと言われてもしょうがないのでは?

どうも下記のように指定するようです。
Private Sub Test(TxtBox As MSForms.TextBox)

これなら TxtBox.SelStart のように候補にもでてきます。

投稿時間:2005/09/16(Fri) 13:14
投稿者名:ダンボ
URL :
タイトル:
Re^2: 【発見】VBAで「型が一致しません」
> Private Sub Test(TxtBox As MSForms.TextBox)

重ね重ね、どうもありがとうございます。すごく納得できました。
会議室の今までの質問・回答を見ても、VBAでは前置詞というか
「どこそこの」コントロールか
「どのシートの」セルか
「どのブックの」「どのシートの」か
というのが重要だなという気がします(あたりまえ)。で、問題は省略したときエラーにせず
不審な動作になること(これもまああたりまえなのかも)

投稿時間:2005/09/16(Fri) 15:42
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re:VBAで「型が一致しません」
> 「どこそこの」コントロールか
> 「どのシートの」セルか
> 「どのブックの」「どのシートの」か

これらは、Excelのグローバルオブジェクトに起因する問題であって、
今回の問題とは、別の内容だったりします。


> > Private Sub Test(TxtBox As MSForms.TextBox)
> で、問題は省略したときエラーにせず
> 不審な動作になること(これもまああたりまえなのかも)

うーん。不審ですか。

個人的には、言語仕様どおりの動作だと思っているのですが、
確かに、ヘルプの記載はわかりにくい & 見つけにくいので、
そう思われても仕方ないかも知れませんね。(^^;


で、少し説明を加えておきますと。

Excelの場合、『コントロール ツール ボックス』に含まれるテキストボックスとは別に、
『図形描画』ツールバーに含まれる、全く別のテキストボックスがありますよね。

これらは、前者が MSForms.TextBox 、後者が Excel.TextBox というオブジェクトとなります。
両者は型名こそ似ていますが、全く異なるオブジェクトなので、今回は型エラーになったわけです。


なお、単に TextBox とだけ書いた場合に、MSForms.TextBox になるか、Excel.TextBox になるかは、
『参照設定』の優先順位によって決定されます。リストの上方に位置している物が優先されるのです。
(この辺りの動作仕様は、言語の説明部だけでなく、「参照設定」画面のヘルプにも少し書かれています)

そのため、単に TextBox と書いた時には、Excel.TextBox の意味となっていたわけです。

ちなみに、この辺りの動作は、VBA でも VB6 でも同様です。
VB6 で単に TextBox と書いた場合は、参照設定優先順により、VB.TextBox 型と解釈されるのですが、
これに Excel.TextBox や MSForms.TextBox を代入した場合は、やはり「型が一致しません」エラーと
なります。

投稿時間:2005/09/16(Fri) 20:20
投稿者名:ダンボ
URL :
タイトル:
Re^2:VBAで「型が一致しません」
魔界の仮面弁士さん、ご説明有難うございます。

> 『図形描画』ツールバーに含まれる、全く別のテキストボックスがありますよね。
> これらは、前者が MSForms.TextBox 、後者が Excel.TextBox というオブジェクトとなります。

「前置詞」が必要なのはそういう理由だったのですか。
Excel.コントロールは、在るのは知っているが全く使ったことがありません。
推察するに、あれはVBAに移行する前の昔のEXCELマクロで使用するものであり下位互換性のために
残してあるものだと思っています。

MSがVBA移行を決断してくれたおかげで、VBひとつ覚えればMS-Officeのマクロが理解しやすくなって
良かったです。

ところが「似て非なるもの」部分があって、例えば今回のHideSelectionプロパティ。
VBAには在るがVB6には無い(VB.Netには在るのでしょうかね)。ということはVBとVBAの
コントロールオブジェクトは、違うモジュールで提供されている。ちょっとリソースの無駄。
かつ知識の無駄がある。いずれ統合するのでしょうね。

投稿時間:2005/09/16(Fri) 21:32
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3:VBAで「型が一致しません」
> ところが「似て非なるもの」部分があって、例えば今回のHideSelectionプロパティ。
> VBAには在るがVB6には無い(VB.Netには在るのでしょうかね)。

……え? 『HideSelection プロパティ』、ですか??

それって、VBA(というかMicrosoft Forms)やVB6どころか、もっと大昔から存在している
プロパティの筈なのですけれどね。。。(^_^;)

何しろ、(16bit版時代の)VB2 にすら実装されていますし。(ちなみに、VB.NET 版にもあります)


> ということはVBとVBAのコントロールオブジェクトは、違うモジュールで提供されている。
> ちょっとリソースの無駄。

う〜ん。私は、それも微妙かな、と感じています。

似た機能であっても、機能等による「棲み分け」が必要な場面はありますので、
異なるモジュールとして提供されるのもアリだろう、と思っています。


具体的な話をすると。

MSForms.TextBox というコントロールは、VB6にて比べるなら、標準コントロールの VB.TextBox と
いうよりも、むしろ VB6 付属の "Microsoft Windowless Controls 6.0" (MSWLESS.OCX) にある
『Lightweight TextBox コントロール(WLText)』に近い存在だったりします。
(WLTextの事はご存知ですか?)

つまり MSForms は、「ウィンドウレス」にする事で、リソース消費量を抑えた
コントロールである、という見方ができるわけです。(軽量化されているわけですね)
他にも MSForms の方は、「Unicodeに対応している」という特徴もあります。


ならば VB.TextBox もWindowlessにすれば良かったのではないか? という考え方も
できそうですが、こちらは OS標準のコントロール(EditBox)をカプセル化したものなので、
これはこれで、「Windows APIを使っての制御が可能である」というメリットもあるわけです。
# まぁ、下位互換性の都合もあったのでしょうけれどね…。


> かつ知識の無駄がある。いずれ統合するのでしょうね。
それはありそうですね。
実際、.NET の世界でも、プロパティ名の統一化などに、その考え方の一端を読みれますし。


ただ、機能的に統合されたとしても、過去の機能で作成されたアプリが完全に無くなるわけでは
無いのですから、統合されたとしても、結局、「新たな選択肢が増えただけ」という事に
なってしまう可能性はあるかも知れませんけれどね。