DOBON.NETプログラミング道掲示板

■35368 / 親記事)  時間変数(文字列)の扱い
  
□投稿者/ ま〜 付き人(57回)-(2023/02/07(Tue) 20:11:18)
  • アイコン環境/言語:[Vs20022 VB] 
    分類:[.NET] 

    いつもお世話になります

    レベルの低い内容ですが
    昔ならこんな感じの事が出来た気がしたんで書いてみましたが

    If Now.ToString("HH:mm") = CStr(DateTimePicker1.ToString("HH:mm")) Then ・・・・

    String=DateTimePicker1.ToString("HH:mm")


    結果は難しい様で
    "String ""HH:mm"" から型 'Integer' への変換は無効です。"
    とエラーとなります

    色々やってるな中で変換の種類によってエラーが変わるのですが
    今回、どうしてInteger扱いになるのか理解出来ずに苦しんでます。

    アドバイスお願いします。
マルチポストを報告
違反を報告
引用返信 削除キー/
■35369 / ResNo.1)  Re[1]: 時間変数(文字列)の扱い
□投稿者/ 魔界の仮面弁士 大御所(1533回)-(2023/02/07(Tue) 21:02:32)
  • アイコンNo35368に返信(ま〜さんの記事)
    > いつもお世話になります
    投稿時に、いろいろと転記ミスをしていませんか?


    > If Now.ToString("HH:mm") = CStr(DateTimePicker1.ToString("HH:mm")) Then ・・・・
    えぇと、
     = CStr(〜.ToString("HH:mm"))

     = 〜.ToString("HH:mm")
    と同義ですよ。文字列を文字列に変換しても無意味かと…。


    それと、DateTimePicker から入力された日付は、
    Value プロパティで取得されます。すなわち
     = DateTimePicker1.ToString("HH:mm")
    ではなく
     = DateTimePicker1.Value.ToString("HH:mm")
    とすべきです。

    とはいえ、DateTimePicker1 の ToString メソッドには
    引数を受け取るオーバーロードは無かったはずなので、本当にその表記なら
    > "String ""HH:mm"" から型 'Integer' への変換は無効です。"
    なエラーではなく、
    「BC30516 この引数の数を受け付ける 'ToString' がないため、オーバーロードの解決に失敗しました。」
    のコンパイルエラーになっているはずですが…?


    なお、書式文字列 ":" はカルチャー依存であり、
    コントロール パネルの設定によっては、
    変換結果が ":" 以外の文字になることがあります。

    カルチャーに依存することなく、常に ":" で返されるようにしたい場合は、
    "HH:mm" の代わりに "HH\:mm" 構文を使います。
    ("HH" や "mm" は、カルチャーに依存しません)

    もっとも、時刻区切りが ":" 以外に設定されているなんてことは
    日本語環境ではまず無いでしょうけれどね。


    > String=DateTimePicker1.ToString("HH:mm")
    String は予約語なので、「String という名前の変数」は作れません。

    予約語を変数名にしたい場合は、
    Dim [String] As String
    のように、角括弧で囲ってエスケープしてください。


    > 結果は難しい様で
    > "String ""HH:mm"" から型 'Integer' への変換は無効です。"
    > とエラーとなります
    コンパイル時エラーではなく、実行時エラーなのですよね?
    (おそらく、Option Strict Off モードでコンパイルしているはず)

    そのエラーが出るケースとして、以下の 2 パターンが想定されます。

    (1) 代入式の左辺が Integer 型の変数やプロパティで、右辺が文字列 "HH:mm" の時
     Dim jikan As Integer = "HH:mm"
     'Dim jikan As Integer = DateTimePicker1.Value.Hour.ToString("HH:mm")

    (2) Integer 型の引数を受け取るメソッドに、"HH:mm" という文字列引数を渡してた時
     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      Test("HH:mm")
     End Sub
     Sub Test(hhmm As Integer)
     End Sub
違反を報告
引用返信 削除キー/
■35370 / ResNo.2)  Re[2]: 時間変数(文字列)の扱い
□投稿者/ ま〜 付き人(58回)-(2023/02/09(Thu) 13:17:30)
  • アイコンいつもありがとうございます
    また、棚ぼたで知識がはいりました。

    > 投稿時に、いろいろと転記ミスをしていませんか?

    ミスに近いかもです。伝えやすい様に Stringは文字列ですと表現したかった感じです。いらぬお手数お掛けしましてすみません 


    >  = DateTimePicker1.Value.ToString("HH:mm")

    ★これでした。Valueが必要でした。


    > 「BC30516 この引数の数を受け付ける 'ToString' がないため、オーバーロードの解決に失敗しました。」
    > のコンパイルエラーになっているはずですが…?

    実行時にその行に来た時にエラーとなっていました


    > (1) 代入式の左辺が Integer 型の変数やプロパティで、右辺が文字列 "HH:mm" の時
    >  Dim jikan As Integer = "HH:mm"
    >  'Dim jikan As Integer = DateTimePicker1.Value.Hour.ToString("HH:mm")
    >
    > (2) Integer 型の引数を受け取るメソッドに、"HH:mm" という文字列引数を渡してた時
    >  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    >   Test("HH:mm")
    >  End Sub
    >  Sub Test(hhmm As Integer)
    >  End Sub

    これ勉強になりました。
    ありがとうございます。

解決み!
違反を報告
引用返信 削除キー/
■35371 / ResNo.3)  Re[3]: 時間変数(文字列)の扱い
□投稿者/ 魔界の仮面弁士 大御所(1534回)-(2023/02/09(Thu) 14:36:13)
  • アイコンNo35370に返信(ま〜さんの記事)
    >> = DateTimePicker1.Value.ToString("HH:mm")
    > ★これでした。Valueが必要でした。
    >>「BC30516 この引数の数を受け付ける 'ToString' がないため、オーバーロードの解決に失敗しました。」
    >>のコンパイルエラーになっているはずですが…?
    > 実行時にその行に来た時にエラーとなっていました

    あー…状況理解。

    今回の場合、
     Dim s1 As String = DateTimePicker1.Value.ToString("HH:mm")
    と書くべきところを、間違えて、
     Dim s2 As String = DateTimePicker1.ToString("HH:mm")
    と書いていたわけですよね。


    DateTimePicker の ToString メソッドは、引数を持つオーバーロードが
    無いにも関わらず、BC30516 が発生しなかった理由は、
     Dim s As String = DateTimePicker1.ToString("HH:mm")
    というコードが、
     Dim s As String = CStr(DateTimePicker1.ToString().Chars(CInt("HH:mm")))
    の意味で、コンパイラに解釈されていたためです。


    Option Strict Off の弊害ですね…。
    Option Strict On でコンパイルが通るコードを目指すことをお奨めします。
    そうすれば、実行前にコーディングミスに気付けるはず!

    ----
    まず、元のコードはこれでした。
     s = DateTimePicker1.ToString("HH:mm")

    しかし、ToString には引数を受け取るオーバーロードが無いため、
    「引数の無いメソッド呼び出しは括弧を省略できる」というルールにより、
     s = DateTimePicker1.ToString()("HH:mm")
    の意味に解釈されます。

    そしてこれは要するに、
     s = DateTimePicker1.ToString().Chars("HH:mm")
    の呼び出しを意味します。

    つまり ("HH:mm") 部分は、「ToString メソッドの引数」ではなく、
    「String 型の既定のプロパティ(いわゆるインデクサ)の引数」と
    解釈されていたわけです。

    しかし、String のインデクサに渡せる引数は Integer 値だけです。

    Option Strict On であれば、この時点でコンパイルエラー
     BC30512『Option Strict On では 'String' から 'Integer' への暗黙的な変換は許可されていません。』
    が発生するので、すぐに気づくことができますが、
    Option Strict Off では検出してもらえません。

    そのため、実行した時点でようやく、
     System.InvalidCastException:
     String "HH:mm" から型 'Integer' への変換は無効です。
    のエラーが発生していた…というわけです。


    Dim v1 = DateTimePicker1.ToString() 'v1 は String 型となる
    Dim v2 = DateTimePicker1.ToString()(0) 'v2 は Char 型となる
解決み!
違反を報告
引用返信 削除キー/
■35375 / ResNo.4)  Re[4]: 時間変数(文字列)の扱い
□投稿者/ ま〜 付き人(59回)-(2023/02/10(Fri) 15:52:31)
  • アイコン変数の件
    ありがとうございます。
    Option Strict Onは知りませんでした。(これが私のレベルなのかも?
    ?)
    また2つ学びました


解決み!
違反を報告
引用返信 削除キー/



スレッド内ページ移動 / << 0 >>

このスレッドに書きこむ

Mode/  Pass/


- Child Tree -