トップ回答者
VBA 実行時エラー13(型が一致しません) の修正について

質問
-
お世話になります。
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
回答
-
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")
tempX = Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd")
datBigin = datBigin + tempX
datEnd = datEnd + tempX - int5- 編集済み KokemomoYamamomo 2019年5月27日 13:11 参考付記
- 回答としてマーク ykaza 2019年5月27日 16:26
-
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
すべての返信
-
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")
tempX = Application.WorksheetFunction.Text(dayEnd, "yyyy/mm/dd")
datBigin = datBigin + tempX
datEnd = datEnd + tempX - int5- 編集済み KokemomoYamamomo 2019年5月27日 13:11 参考付記
- 回答としてマーク ykaza 2019年5月27日 16:26
-
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
-