• ベストアンサー

タイムスタンプの更新の方法2

前回の質問の方法が悪かったので改めて質問させていただきます。よろしくお願い致します。 現在開いていないファイルのタイムスタンプを任意の日時にエクセルVBAから変更する方法をご伝授頂けないでしょうか?タイムスタンプの取得は簡単に出来そうなんですが、書き込み方法が解らず困っています。 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.4

すみません、、、 #3 の SetTIMESTAMP 関数で、  Dim FSO As New FileSystemObject は参照設定でコードを書いていたなごりです。 このまま参照設定しないとエラーになりますので、  Dim FSO As Object に修正いたします。

vba_minarai
質問者

補足

すごい!すごい!すごい!の言葉しかでてきません! 私が、質問をアップしたのが、21:28! 第一回目のご指導が、日が変わって間もない1:44! それを、ライブラリー化したのが、11:41! 更に、訂正を加えたのが、12:22! サスペンスドラマなら、この短時間で一人で犯行を犯すのは絶対に不可能!!この事件は、複数犯であると警部が断定し迷宮入りとなるでしょう! 横に、見本があって、単に打ち込むだけでも、同じぐらいの時間がかかります。私は!しかも、内容の大部分が私の知っているベーシックではなく、ウルトラ文字で書いたてあり、辞書を片手に1字1字調べなきゃ読めん!!でも、使い方まで書いてある!! あっ!判った!21:28以前に私が質問するのを察知していたのだなぁ? って、感じです。感服致します。密かに、いつの日か?KenKen_SPのコードも素晴らしいのだけど、こんな表記もありますよ!!って、答える側に回ることを夢見ていましたが、現実を見ました。やはり、ガリバーには、カナイマセン!!師匠についていきます!何処までも!! ショックが大きすぎて、お礼はまたの機会にします。ほんとうにありがとう御座いました。コードを打ち出して、壁に貼っておきます。今後とも宜しくお願いします。なんだか?質問が数行だけなのが申し訳ないです!! (絶対に、読破してやる~!!)

その他の回答 (3)

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.3

再びこんにちは。KenKen_SP です。 自分でも使うだろうからタイムスタンプの取得・設定をライブラリー化して みました。ちょっと仰々しいコードですが、ご参考までで。 フォルダのタイムスタンプにも対応してます。(設定はNT系OSのみ) 詳しい説明は省略しますが、末尾のサンプルコードを見て下さい。 Option Explicit '// Win32API ファイルを作成またはオープン Private Declare Function CreateFile Lib "kernel32.dll" _   Alias "CreateFileA" ( _   ByVal lpFileName As String, _   ByVal dwdesiredAccess As Long, _   ByVal dwShareMode As Long, _   ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, _   ByVal dwCreationDisposition As Long, _   ByVal dwFlagsAndAttributes As Long, _   ByVal hTemplateFile As Long) As Long '// Win32API ファイルやディレクトリの属性を取得 Private Declare Function GetFileAttributes Lib "kernel32.dll" _   Alias "GetFileAttributesA" ( _   ByVal lpFileName$) As Long   '// Win32API 開かれているオブジェクトのハンドルを開放 Private Declare Function CloseHandle Lib "kernel32.dll" ( _   ByVal hObject As Long) As Long '// Win32API システムタイムをファイルタイムに変換する Private Declare Function SystemTimeToFileTime Lib "kernel32.dll" ( _   ByRef lpSystemTime As SYSTEMTIME, _   ByRef lpFileTime As FILETIME) As Long '// Win32API ローカルファイルタイムをUTCファイルタイム形式で取得する Private Declare Function LocalFileTimeToFileTime Lib "kernel32.dll" ( _   ByRef lpLocalFileTime As FILETIME, _   ByRef lpFileTime As FILETIME) As Long '// Win32API ファイルのファイルタイムを設定する Private Declare Function SetFileTime Lib "kernel32.dll" ( _   ByVal hFile As Long, _   ByRef lpCreationTime As FILETIME, _   ByRef lpLastAccessTime As FILETIME, _   ByRef lpLastWriteTime As FILETIME) As Long '// SECURITY_ATTRIBUTES 構造体 Private Type SECURITY_ATTRIBUTES   nLength       As Long '構造体のバイト数   lpSecurityDescriptor As Long 'セキュリティデスクリプタ(Win95,98では無効)   bInheritHandle    As Long '1のとき属性を継承する End Type '// SYSTEMTIME 構造体 Private Type SYSTEMTIME   wYear     As Integer '年   wMonth    As Integer '月   wDayOfWeek  As Integer '曜日(日=0, 月=1 ...)   wDay     As Integer '日   wHour     As Integer '時   wMinute    As Integer '分   wSecond    As Integer '秒   wMilliseconds As Integer 'ミリ秒 End Type '// FILETIME 構造体 Private Type FILETIME   dwLowDateTime As Long  '下位32ビット値   dwHighDateTime As Long  '上位32ビット値 End Type '// 定数 Private Const FILE_FLAG_BACKUP_SEMANTICS As Long = &H2000000 'NT系OSのみ Private Const GENERIC_READ        As Long = &H80000000 Private Const GENERIC_WRITE       As Long = &H40000000 Private Const FILE_SHARE_READ      As Long = &H1 Private Const FILE_ATTRIBUTE_NORMAL   As Long = &H80 Private Const OPEN_EXISTING       As Long = 3 Private Const OPEN_ALWAYS        As Long = 4 Private Const INVALID_HANDLE_VALUE    As Long = &HFFFFFFFF '// ファイルまたはフォルダのタイムスタンプ設定関数 2005/11/28 Public Function SetTIMESTAMP( _   ByVal strFULLPATH As String, _   Optional ByVal datCREATETIME As Date, _   Optional ByVal datACCESSTIME As Date, _   Optional ByVal datMODIFYTIME As Date) As Boolean      Dim lngHANDLE As Long   Dim lngFLAG  As Long   Dim lngRET  As Long   Dim udtCREATE As FILETIME   Dim udtACCESS As FILETIME   Dim udtMODIFY As FILETIME   Dim udtSEQRTY As SECURITY_ATTRIBUTES   Dim FSO As New FileSystemObject   Dim OBJ As Object      '// 対象の存在チェックとdwFlagsAndAttributes の設定   Set FSO = CreateObject("Scripting.FileSystemObject")   If FSO.FileExists(strFULLPATH) Then     'ファイルの場合     Set OBJ = FSO.GetFile(strFULLPATH)     lngFLAG = FILE_ATTRIBUTE_NORMAL   ElseIf FSO.FolderExists(strFULLPATH) Then     'フォルダの場合(NT系のOSのみ可能)     If InStr(Application.OperatingSystem, "NT") > 0 Then       Set OBJ = FSO.GetFolder(strFULLPATH)       lngFLAG = FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_BACKUP_SEMANTICS     Else       GoTo TERMINATE     End If   Else     'ファイルもフォルダも見つからない場合     GoTo TERMINATE   End If      '// オプション引数が省略された場合は現状のものを補完   With OBJ     If datCREATETIME = 0 Then datCREATETIME = .DateCreated     If datACCESSTIME = 0 Then datACCESSTIME = .DateLastAccessed     If datMODIFYTIME = 0 Then datMODIFYTIME = .DateLastModified   End With   '// SECURITY_ATTRIBUTES構造体初期化   With udtSEQRTY     .nLength = LenB(udtSEQRTY)     .lpSecurityDescriptor = 0&     .bInheritHandle = 0&   End With      '// ファイルまたはフォルダハンドルを取得   lngHANDLE = CreateFile(strFULLPATH, GENERIC_WRITE, _     FILE_SHARE_READ, udtSEQRTY, OPEN_EXISTING, lngFLAG, vbNull)   If lngHANDLE = INVALID_HANDLE_VALUE Then GoTo TERMINATE        '// ファイルタイムに変換し、設定する   udtCREATE = GetFILETIME(datCREATETIME)   udtACCESS = GetFILETIME(datACCESSTIME)   udtMODIFY = GetFILETIME(datMODIFYTIME)   lngRET = SetFileTime(lngHANDLE, udtCREATE, udtCREATE, udtMODIFY)   If lngRET <> 0 Then SetTIMESTAMP = True      '// ファイルまたはフォルダハンドル開放   CloseHandle lngHANDLE TERMINATE:   Set OBJ = Nothing   Set FSO = Nothing End Function '// ファイルまたはフォルダのタイムスタンプ取得関数 2005/11/28 Public Function GetTIMESTAMP( _   ByVal strFULLPATH As String, _   ByRef datCREATETIME As Date, _   ByRef datACCESSTIME As Date, _   ByRef datMODIFYTIME As Date) As Boolean        Dim FSO As Object 'New FileSystemObject   Dim OBJ As Object   Set FSO = CreateObject("Scripting.FileSystemObject")   If FSO.FileExists(strFULLPATH) Then     Set OBJ = FSO.GetFile(strFULLPATH)   ElseIf FSO.FolderExists(strFULLPATH) Then     Set OBJ = FSO.GetFolder(strFULLPATH)   Else     GoTo TERMINATE   End If   With OBJ     datCREATETIME = CDate(.DateCreated)     datACCESSTIME = CDate(.DateLastAccessed)     datMODIFYTIME = CDate(.DateLastModified)   End With   GetTIMESTAMP = True    TERMINATE:   Set OBJ = Nothing   Set FSO = Nothing   Exit Function    ERROR_HANDLER:   GetTIMESTAMP = 0   GoTo TERMINATE    End Function '// UTCファイルタイム変換関数 2005/11/28 Private Function GetFILETIME(ByVal datPARAM As Date) As FILETIME      Dim udtSysTime As SYSTEMTIME   Dim udtLclTime As FILETIME   With udtSysTime     .wYear = Year(datPARAM)     .wMonth = Month(datPARAM)     .wDayOfWeek = Weekday(datPARAM)     .wDay = Day(datPARAM)     .wHour = Hour(datPARAM)     .wMinute = Minute(datPARAM)     .wSecond = Second(datPARAM)     .wMilliseconds = 0   End With   Call SystemTimeToFileTime(udtSysTime, udtLclTime)   Call LocalFileTimeToFileTime(udtLclTime, GetFILETIME) End Function '// 使い方サンプル Sub SampleCode()   Dim strPATH As String   Dim datCREATETIME As Date   Dim datACCESSTIME As Date   Dim datMODIFYTIME As Date      strPATH = Application.GetOpenFilename("ファイル (*.*), *.*")   If UCase$(strPATH) = "FALSE" Then     Exit Sub   End If   '// タイムスタンプ取得サンプル   If GetTIMESTAMP(strPATH, datCREATETIME, datACCESSTIME, datMODIFYTIME) Then          MsgBox "タイムスタンプを取得しました" & vbCrLf & _         "CREATE:= " & CStr(datCREATETIME) & vbCrLf & _         "MODIFY:= " & CStr(datMODIFYTIME) & vbCrLf & _         "ACCESS:= " & CStr(datACCESSTIME) & vbCrLf, vbInformation   Else     MsgBox "タイムスタンプ取得に失敗しました", vbCritical     Exit Sub   End If      MsgBox "更新日時を現在(Now関数の戻り値)に設定します", vbInformation        '// タイムスタンプ設定サンプル   '更新日時を現在(Now関数の戻り値)に設定します   If SetTIMESTAMP(strPATH, , , Now()) Then     Call GetTIMESTAMP(strPATH, datCREATETIME, datACCESSTIME, datMODIFYTIME)     MsgBox "タイムスタンプを更新しました。" & vbCrLf & _         "CREATE:= " & CStr(datCREATETIME) & vbCrLf & _         "MODIFY:= " & CStr(datMODIFYTIME) & vbCrLf & _         "ACCESS:= " & CStr(datACCESSTIME) & vbCrLf, vbInformation   Else     MsgBox "タイムスタンプ設定に失敗しました", vbCritical   End If End Sub

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.2

こんにちは。KenKen_SP です。 タイムスタンプは VBA の FileDateTime 関数でも取得できますが、FileSystemObject でも取得できます。ファイルシステムに関する処理には非常に便利ですから、こちらも覚えておいて損はないです。今回の関数内でも使用しています。 タイムスタンプの設定については、残念ながら VBA と VB6までには関数が用意されてません。これを実現するためには Win32Api を使うことになりますが、結構面倒くさいですね。関数化してみましたが、結構長いコードになってしまいました。 国内で使用する場合は問題ないと思いますが、ひょっとするとタイムゾーンの相違とか、OS とファイルシステムの組み合わせなどが原因となってコケる可能性があります。(手抜きです) 一番下に使い方サンプルを書いておきましたが、仕様は次のとおりです。   SetTIMESTAMP(ファイルのフルパス,作成日時,最終アクセス日時,更新日時) 戻り値は成功すると True、失敗で False を返します。ファイルパス以外はオプションですから指定しなくても構いません。例えば、作成日時だけを現在時刻にするなら、   Call SetTIMESTAMP("C:\Test.xls",Now()) だし、更新日時のみを設定するなら、   Call SetTIMESTAMP("C:\Test.xls", , ,Now()) です。省略された部分は変更前のタイムスタンプがそのまま維持されます。なお、ファイルが既に開かれていたり、読み取り専用属性などがついているとタイムスタンプの変更に失敗しますが、エラートラップしてありますので、関数の実行結果としては False が返ります。 では。 Option Explicit '// Win32Api ファイルを作成またはオープン Private Declare Function CreateFile Lib "kernel32.dll" Alias "CreateFileA" ( _   ByVal lpFileName As String, _   ByVal dwdesiredAccess As Long, _   ByVal dwShareMode As Long, _   ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, _   ByVal dwCreationDisposition As Long, _   ByVal dwFlagsAndAttributes As Long, _   ByVal hTemplateFile As Long) As Long    '// Win32Api 開かれているオブジェクトのハンドルを開放 Private Declare Function CloseHandle Lib "kernel32.dll" ( _   ByVal hObject As Long) As Long '// Win32Api システムタイムをファイルタイムに変換する Private Declare Function SystemTimeToFileTime Lib "kernel32.dll" ( _   ByRef lpSystemTime As SYSTEMTIME, _   ByRef lpFileTime As FILETIME) As Long '// Win32Api ローカルファイルタイムをUTCファイルタイム形式で取得する Private Declare Function LocalFileTimeToFileTime Lib "kernel32.dll" ( _   ByRef lpLocalFileTime As FILETIME, _   ByRef lpFileTime As FILETIME) As Long '// Win32Api ファイルのファイルタイムを設定する Private Declare Function SetFileTime Lib "kernel32.dll" ( _   ByVal hFile As Long, _   ByRef lpCreationTime As FILETIME, _   ByRef lpLastAccessTime As FILETIME, _   ByRef lpLastWriteTime As FILETIME) As Long '// SECURITY_ATTRIBUTES構造体 Private Type SECURITY_ATTRIBUTES   nLength As Long       '構造体のバイト数   lpSecurityDescriptor As Long 'セキュリティデスクリプタ(Win95,98では無効)   bInheritHandle As Long    '1のとき属性を継承する End Type '// SYSTEMTIME構造体 Private Type SYSTEMTIME   wYear     As Integer '現在の年   wMonth    As Integer '月   wDayOfWeek  As Integer '曜日(日=0, 月=1 ...)   wDay     As Integer '日   wHour     As Integer '時   wMinute    As Integer '分   wSecond    As Integer '秒   wMilliseconds As Integer 'ミリ秒 End Type '// FILETIME構造体 Private Type FILETIME   dwLowDateTime As Long  '下位32ビット値   dwHighDateTime As Long  '上位32ビット値 End Type '// 定数 Private Const GENERIC_READ     As Long = &H80000000 Private Const GENERIC_WRITE     As Long = &H40000000 Private Const FILE_SHARE_READ    As Long = &H1 Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80 Private Const OPEN_EXISTING     As Long = 3 Private Const OPEN_ALWAYS      As Long = 4 '// ファイルタイム変換 Private Function GetFILETIME(ByVal datPARAM As Date) As FILETIME      Dim udtSysTime As SYSTEMTIME   Dim udtLclTime As FILETIME   With udtSysTime     .wYear = Year(datPARAM)     .wMonth = Month(datPARAM)     .wDayOfWeek = Weekday(datPARAM)     .wDay = Day(datPARAM)     .wHour = Hour(datPARAM)     .wMinute = Minute(datPARAM)     .wSecond = Second(datPARAM)     .wMilliseconds = 0   End With   Call SystemTimeToFileTime(udtSysTime, udtLclTime)   Call LocalFileTimeToFileTime(udtLclTime, GetFILETIME) End Function '// ファイルのタイムスタンプを設定 Public Function SetTIMESTAMP(ByVal strFILE_FULLPATH As String, _   Optional ByVal datCREATETIME As Date, _   Optional ByVal datACCESSTIME As Date, _   Optional ByVal datMODIFYTIME As Date) As Boolean      Dim lngFILEHL As Long   Dim lngRET  As Long   Dim udtCREATE As FILETIME   Dim udtACCESS As FILETIME   Dim udtMODIFY As FILETIME   Dim udtSEQRTY As SECURITY_ATTRIBUTES      If Dir(strFILE_FULLPATH) = "" Then Exit Function      '// SECURITY_ATTRIBUTES構造体初期化   With udtSEQRTY     .nLength = LenB(udtSEQRTY)     .lpSecurityDescriptor = 0&     .bInheritHandle = 0&   End With   '// ファイルハンドル取得   lngFILEHL = CreateFile( _     strFILE_FULLPATH, _     GENERIC_WRITE, _     FILE_SHARE_READ, _     udtSEQRTY, _     OPEN_EXISTING, _     FILE_ATTRIBUTE_NORMAL, _     vbNull)   If lngFILEHL = &HFFFFFFFF Then Exit Function 'Invalid Handle      '// オプション引数が省略された場合は現状のものを補完   Dim FSO As Object   Set FSO = CreateObject("Scripting.FileSystemObject")   With FSO.GetFile(strFILE_FULLPATH)     If datCREATETIME = 0 Then datCREATETIME = .DateCreated     If datACCESSTIME = 0 Then datACCESSTIME = .DateLastAccessed     If datMODIFYTIME = 0 Then datMODIFYTIME = .DateLastModified   End With   Set FSO = Nothing      '// ローカルタイムをUTCファイルタイム形式に変換   udtCREATE = GetFILETIME(datCREATETIME)   udtACCESS = GetFILETIME(datACCESSTIME)   udtMODIFY = GetFILETIME(datMODIFYTIME)      '// タイムスタンプ設定   lngRET = SetFileTime(lngFILEHL, udtCREATE, udtACCESS, udtMODIFY)   If lngRET <> 0 Then SetTIMESTAMP = True      '// ファイルハンドルを開放   CloseHandle lngFILEHL End Function '// 使い方サンプル Sub SampleCode()      '現在(Now関数の戻り値)に変更してみます   If SetTIMESTAMP("C:\test.txt", Now(), Now(), Now()) Then     MsgBox "タイムスタンプを設定しました", vbInformation   Else     MsgBox "タイムスタンプの設定に失敗しました", vbCritical   End If    End Sub

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんばんは。Wendy02です。 >ディレクトリーに記載されているタイムスタンプをバージョン表記にしたいと考えています。 通常、私などは、Office製品では、 BuiltinDocumentProperties や CustomDocumentProperties を使いますね。以下のように使います。 Sub RevisionSetting() '版の設定  ThisWorkbook.BuiltinDocumentProperties(8) = 1 'Revision number End Sub '終了ごとに、0.1 を足すなどすればよいでしょう。 Sub RevisionShowUp() '版の閲覧  MsgBox ThisWorkbook.BuiltinDocumentProperties(8) End Sub 設定すると、プロパティの統計(タブ)の改定番号という場所に記載されます。 それと、私は、Win32 APIのApiViewer のアドインは使っていますし、資料もいくつかはあるのですが、今のところ、自力では組めないので、以下をご覧になってください。それは、私の範囲外です。 SetFileTime 関数を使うようですが。 http://www31.ocn.ne.jp/~heropa/vb02.htm ファイルのタイムスタンプの取得・設定 http://jeanne.wankuma.com/tips/file/09-settimestamp.html ファイルのタイムスタンプを設定する

vba_minarai
質問者

補足

いつも、いつもありがとう御座います。 BuiltinDocumentProperties?stomDocumentProperties ?また、新しい言葉が出てきました!! いつもながら、学ぶこと一杯です。最終的には、VBとVCを一緒に習得していかなきゃ、マスター(何を持ってマスターと言うかは別にして・・)出来ないのかも?って思いはじめました。構造体や、API、クラス、プロパティプロシージャーなんてあまり、VBAの本には載っていないですから?この上、次のエクセルが.NETに対応すると、もう、雲の上の存在になるんでしょうか?VBAが無くなってしまったらどうしよう?って思います。早く、初心者を卒業して初級者になれるように、もっと、ガンバロウ!!って思います。ますますのご指導のほどよろしくお願い致します。本当にありがとう御座いました。

関連するQ&A