none
VBA 実行時エラー13(型が一致しません) の修正について RRS feed

  • 質問

  • お世話になります。

    VBAについて全くの素人なので丸投げのような質問の仕方になってしまい申し訳ないのですが、
    下記の☆☆☆☆☆☆☆☆より下のコードを実行すると実行時エラー13(型が一致しません)
    となり上手く実行できません。

    デバックすると上から15行目の

    datBigin = datBigin + Application.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd")

    が黄色くなるのでここが原因かと思うのですが、どこを修正すればエラーなく実行できるでしょうか。
    大雑把な質問で申し訳ないのですが、ご教授いただけると助かります。

    よろしくお願い致します。

    ☆☆☆☆☆☆☆☆

    Dim mcolTask As Collection

    Sub Tasc_Bigin()
    ' セッティング-------------------------------------------------------
        dayBigin = "2019/05/27"               ' 開始日付
        datBigin = TimeValue("14:25:00")    ' 開始時刻
        dayEnd = "2019/05/27"                 ' 終了日付
        datEnd = TimeValue("14:30:00")      ' 終了時刻
        datInterval = TimeValue("00:00:15") ' 実行間隔(少なくとも数秒以上で)
        datTimeout = TimeValue("00:02:00")  ' 実行待機タイムアウト
        blnJustTime = True                  ' datInterval で丸めるか
        strProcName = "Ashi"              ' 実行するマクロ名
        int5 = TimeValue("00:00:05")        ' 設定した終了時間からのマイナス時間
    '---------------------------------------------------------------

    If mcolTask Is Nothing Then
        ' 日付シリアル値を加算
        datBigin = datBigin + Application.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd")
        datEnd = datEnd + Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd") - int5
        
        If datEnd < datBigin Then
            MsgBox "開始日時が終了日時より遅くなっています。"
            Exit Sub
        End If
        
        ' 現在時刻が既に終了時刻を過ぎている場合
        If datEnd < Now() Then
            MsgBox "終了時刻を過ぎているため予約できません。", vbCritical, "終了"
            Exit Sub
        End If
        
        ' 現在時刻が開始時刻を過ぎていれば補正
        If datBigin <= Now() Then
            ' 開始時刻を datInterval で指定された値で丸めるか
            If blnJustTime Then
                datBigin = Application.Floor(Now() + datInterval, datInterval)
            Else
                datBigin = Now() + datInterval
            End If
        End If

        ' 初期化
        Set mcolTask = New Collection

        ' メイン部分
        For i = datBigin To datEnd Step datInterval
            ' 後から取り消せるようにコレクションに退避
            mcolTask.Add CStr(i) & "," & strProcName
            ' Application.Ontime で実行予約を行う
            Application.OnTime EarliestTime:=i, _
                                Procedure:=strProcName, _
                                LatestTime:=i + datTimeout, _
                                Schedule:=True
        Next i


    Else
        MsgBox "既に実行中です", vbInformation
    End If

            
    Exit Sub
        
    error:
      MsgBox "エラーが発生しました。設定された日時をご確認ください。"
            

    End Sub


    2019年5月27日 12:25

回答

  • ykazaさん、こんばんは。

    変数の定義がされていないので、されるようにした方が良いと思うのですが、それはさておき、

    エラーとなる1文の左辺のdatBiginはdate型の変数と理解。

    一方、右辺のApplication.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd")はstring型。

    従って、型が一致しません。

    CDate()で型を変換すれば、エラーは出なくなります。

    datBigin = datBigin + CDate(Application.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd"))

    なお、その次の文も同じ。

    datEnd = datEnd + CDate(Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd")) - int5

    以上でどうでしょうか。

    なお、VBAでは、勝手に変数の型をアジャストしてくれる機能があるようですが、元のスクリプトの様な場合には、無理だという事のようですね。小生は、変数は必ず定義しているので、決してお勧めするわけではありませんが、例えば、Dim tempX as Date と定義をしたうえで、問題の1文を次の2文にすると、エラーは出なくなるようです。決してお勧めするわけではないですが、ご参考まで。その次の文も同様。

    tempX = Application.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd")
    datBigin = datBigin + tempX

    tempX = Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd")
    datEnd = datEnd + tempX - int5
    • 編集済み KokemomoYamamomo 2019年5月27日 13:11 参考付記
    • 回答としてマーク ykaza 2019年5月27日 16:26
    2019年5月27日 12:43
  • VBA で時間の計算をする場合は Date 型を使うようにしましょう。
    また、Date 型の計算は Date 型を対象にするならそのまま加算や減算ができますが
    可能なら DateAdd を使った方がいいです。

    Option Explicit
    
    Sub test()
        Dim dateBigin As Date, dateEnd As Date, datEnd As Date, _
            datInterval As Date, datTimeout As Date, int5 As Date, dateNow As Date
        Dim blnJustTime As Boolean
        Dim strProcName As String
    
        ' Date 型変数の使い方例
    
        ' 開始日時
        ' CDate で Date 型形式の文字列をキャスト
        ' そのまま、dayBigin = "2019/05/27 14:25:00" や
        ' dayBigin = #5/27/2019 2:25:00 PM# などとしても OK
        dateBigin = CDate("2019/05/27 14:25:00")
    
        ' 終了日時
        ' Date 型変数に Date 型にキャストできる文字列を代入
        dateEnd = "2019/05/27 14:30:00"
    
        ' 実行間隔 (少なくとも数秒以上で)
        ' Date 型定数 (#m/d/yyyy h:mm:ss AM/PM# の形式)
        ' #00:00:15# と入力すると自動的に以下の形に修正される
        datInterval = #12:00:15 AM#
    
        ' 実行待機タイムアウト
        ' TimeValue で Date 型にキャスト
        datTimeout = TimeValue("00:02:00")
    
        ' 実数を CDate で Date 型にキャスト
        ' (この場合はわかりにくいのであまりしないと思う)
        ' 設定した終了時間からのマイナス時間
        ' 1 (日) / 24 (時間) / 60 (分) / 60 (秒) * 5 (秒) ≒ 00:00:05
        int5 = CDate(1 / 24 / 60 / 60 * 5)
    
        ' 丸め
        blnJustTime = True
        ' 実行するマクロ名
        strProcName = "Ashi"
    
        ' (中略)
    
        ' 日付シリアル値を加算
        ' 対象が秒でない場合などは適宜修正
        datEnd = DateAdd("s", -Second(int5), dateEnd)
        If datEnd < dateBigin Then
            MsgBox "開始日時が終了日時より遅くなっています。"
            Exit Sub
        End If
    
        dateNow = Now
        ' 現在時刻が既に終了時刻を過ぎている場合
        If datEnd < dateNow Then
             MsgBox "終了時刻を過ぎているため予約できません。", vbCritical, "終了"
             Exit Sub
         End If
         
         ' 現在時刻が開始時刻を過ぎていれば補正
        If dateBigin <= dateNow Then
            ' 開始時刻を datInterval で指定された値で丸めるか
            dateBigin = IIf(blnJustTime, _
                DateAdd("s", _
                    Second(datInterval) - dateNow Mod Second(datInterval), _
                    dateNow), _
                CDate(dateNow + datInterval))
        End If
    
        ' (後略)
    End Sub


    • 編集済み infade 2019年5月27日 14:55 少々、整形
    • 回答としてマーク ykaza 2019年5月27日 16:57
    2019年5月27日 14:41

すべての返信

  • ykazaさん、こんばんは。

    変数の定義がされていないので、されるようにした方が良いと思うのですが、それはさておき、

    エラーとなる1文の左辺のdatBiginはdate型の変数と理解。

    一方、右辺のApplication.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd")はstring型。

    従って、型が一致しません。

    CDate()で型を変換すれば、エラーは出なくなります。

    datBigin = datBigin + CDate(Application.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd"))

    なお、その次の文も同じ。

    datEnd = datEnd + CDate(Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd")) - int5

    以上でどうでしょうか。

    なお、VBAでは、勝手に変数の型をアジャストしてくれる機能があるようですが、元のスクリプトの様な場合には、無理だという事のようですね。小生は、変数は必ず定義しているので、決してお勧めするわけではありませんが、例えば、Dim tempX as Date と定義をしたうえで、問題の1文を次の2文にすると、エラーは出なくなるようです。決してお勧めするわけではないですが、ご参考まで。その次の文も同様。

    tempX = Application.WorksheetFunction.Text(dayBigin, "yyyy/mm/dd")
    datBigin = datBigin + tempX

    tempX = Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd")
    datEnd = datEnd + tempX - int5
    • 編集済み KokemomoYamamomo 2019年5月27日 13:11 参考付記
    • 回答としてマーク ykaza 2019年5月27日 16:26
    2019年5月27日 12:43
  • VBA で時間の計算をする場合は Date 型を使うようにしましょう。
    また、Date 型の計算は Date 型を対象にするならそのまま加算や減算ができますが
    可能なら DateAdd を使った方がいいです。

    Option Explicit
    
    Sub test()
        Dim dateBigin As Date, dateEnd As Date, datEnd As Date, _
            datInterval As Date, datTimeout As Date, int5 As Date, dateNow As Date
        Dim blnJustTime As Boolean
        Dim strProcName As String
    
        ' Date 型変数の使い方例
    
        ' 開始日時
        ' CDate で Date 型形式の文字列をキャスト
        ' そのまま、dayBigin = "2019/05/27 14:25:00" や
        ' dayBigin = #5/27/2019 2:25:00 PM# などとしても OK
        dateBigin = CDate("2019/05/27 14:25:00")
    
        ' 終了日時
        ' Date 型変数に Date 型にキャストできる文字列を代入
        dateEnd = "2019/05/27 14:30:00"
    
        ' 実行間隔 (少なくとも数秒以上で)
        ' Date 型定数 (#m/d/yyyy h:mm:ss AM/PM# の形式)
        ' #00:00:15# と入力すると自動的に以下の形に修正される
        datInterval = #12:00:15 AM#
    
        ' 実行待機タイムアウト
        ' TimeValue で Date 型にキャスト
        datTimeout = TimeValue("00:02:00")
    
        ' 実数を CDate で Date 型にキャスト
        ' (この場合はわかりにくいのであまりしないと思う)
        ' 設定した終了時間からのマイナス時間
        ' 1 (日) / 24 (時間) / 60 (分) / 60 (秒) * 5 (秒) ≒ 00:00:05
        int5 = CDate(1 / 24 / 60 / 60 * 5)
    
        ' 丸め
        blnJustTime = True
        ' 実行するマクロ名
        strProcName = "Ashi"
    
        ' (中略)
    
        ' 日付シリアル値を加算
        ' 対象が秒でない場合などは適宜修正
        datEnd = DateAdd("s", -Second(int5), dateEnd)
        If datEnd < dateBigin Then
            MsgBox "開始日時が終了日時より遅くなっています。"
            Exit Sub
        End If
    
        dateNow = Now
        ' 現在時刻が既に終了時刻を過ぎている場合
        If datEnd < dateNow Then
             MsgBox "終了時刻を過ぎているため予約できません。", vbCritical, "終了"
             Exit Sub
         End If
         
         ' 現在時刻が開始時刻を過ぎていれば補正
        If dateBigin <= dateNow Then
            ' 開始時刻を datInterval で指定された値で丸めるか
            dateBigin = IIf(blnJustTime, _
                DateAdd("s", _
                    Second(datInterval) - dateNow Mod Second(datInterval), _
                    dateNow), _
                CDate(dateNow + datInterval))
        End If
    
        ' (後略)
    End Sub


    • 編集済み infade 2019年5月27日 14:55 少々、整形
    • 回答としてマーク ykaza 2019年5月27日 16:57
    2019年5月27日 14:41
  • KokemomoYamamomoさん、返信ありがとうございます。

    アドバイス通りCDate()で型を変換たところ、エラーにならずに実行することができました。

    型が違ってエラーとなっているというのはエラー13で調べて何となく分かっていたのですが、
    どう変換すればいいのかが分からず困っていたので非常に助かりました。

    他にも変数の定義などのアドバイスもして頂きありがとうございます。
    お勧めのやり方でないにしても違ったアプローチの方法として今後の参考にさせて頂きます。

    今回は回答ありがとうございました。
    またよろしくお願い致します。




    2019年5月27日 16:26
  • infadeさん、返信ありがとうございます。

    Date 型の使用例を詳細にアドバイスして頂きありがとうございます。
    私は変数の宣言や型すらイマイチ分かっていないので理解するのに多少時間がかかってしまうと思いますが、
    具体的に使用例を示して頂いたので、理解しやすそうで非常に助かります。

    詳しく回答して頂きありがとうございました。
    またよろしくお願い致します。


    2019年5月27日 16:57