У меня есть код, который показан ниже, главное - внести некоторые изменения в файл .accdb, сохранив существующие атрибуты CreationTime, LastAccessTime и LastWriteTime этого файла.
Все отлично работает, но я столкнулся с этой проблемой:
Оригинальные проекты MS Access (тысячи файлов .accdb) содержат макросы VBA. Стандартная политика: «Отключить все макросы с уведомлением». Поэтому, как только пользователь нажал кнопку, файл сохраняет свои предпочтения (только для этого файла) - и это нормально.
Но после того, как я внесу изменения в файл с помощью следующего сценария, он сбрасывает настройки безопасности для этого точного файла, и в следующий раз, когда пользователь открывает базу данных, появляется желтое «Предупреждение о безопасности» (все макросы и активное содержимое совпадают , ничего нового!).
Проблема в том, что у меня есть тысячи файлов accdb. Мне нужно внести небольшие изменения, но сохранить существующие атрибуты.
И когда пользователи откроют эти файлы, не должно быть новой панели предупреждений безопасности.
Я могу, но я не хочу:
изменить настройки безопасности для активного содержимого
сделать эту папку надежной папкой
любые другие изменения параметров безопасности, такие как Regedit и так далее.
Я НЕ добавляю никаких макросов или активного контента, сообщение появляется, потому что, я думаю, некоторые настройки после использования CreateFileA были изменены.
(например, если я вручную переименую файл, MS Access думает, что это другой файл - и показывает панель безопасности - и это правильно; но почему он появляется после изменения атрибутов файла?)
Спасибо!
Постскриптум Мы используем MS Access 2016.
Option Explicit
Public Const GENERIC_WRITE = &H40000000, GENERIC_READ = &H80000000, FILE_ATTRIBUTE_NORMAL = &H80, OPEN_EXISTING = 3
Public Type FileTime: dwLowDateTime As Long: dwHighDateTime As Long: End Type
Public Type SYSTEMTIME: wYear As Integer: wMonth As Integer: wDayOfWeek As Integer: wDay As Integer: wHour As Integer: wMinute As Integer: wSecond As Integer: wMilliseconds As Integer: End Type
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFilename As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Declare Function SetFileTime Lib "kernel32" (ByVal hFile As Long, lpCreationTime As FileTime, lpLastAccessTime As FileTime, lpLastWriteTime As FileTime) As Long
Declare Function GetFileTime Lib "kernel32" (ByVal hFile As Long, lpCreationTime As FileTime, lpLastAccessTime As FileTime, lpLastWriteTime As FileTime) As Long
Declare Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FileTime) As Long
Declare Function LocalFileTimeToFileTime Lib "kernel32" (lpFileTime As FileTime, lpLocalFileTime As FileTime) As Long
Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FileTime, lpSystemTime As SYSTEMTIME) As Long
Declare Function FileTimeToLocalFileTime Lib "kernel32" (lpLocalFileTime As FileTime, lpFileTime As FileTime) As Long
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public GlobCreationDate As Date, GlobLastAccess As Date, GlobLastWrite As Date
Public FileAddress As String
Function DTtoFT(ByVal DT As Date) As FileTime 'DateTimeToFileTime
Dim ST As SYSTEMTIME, lTime As FileTime
ST.wYear = Year(DT): ST.wMonth = Month(DT): ST.wDay = Day(DT): ST.wHour = Hour(DT): ST.wMinute = Minute(DT): ST.wSecond = Second(DT)
SystemTimeToFileTime ST, lTime
LocalFileTimeToFileTime lTime, DTtoFT
End Function
Function FTtoDT(FT As FileTime) As Date 'FileTimeToDateTime
Dim lTime As FileTime, ST As SYSTEMTIME
FileTimeToLocalFileTime FT, lTime
FileTimeToSystemTime lTime, ST
FTtoDT = DateSerial(ST.wYear, ST.wMonth, ST.wDay) + TimeSerial(ST.wHour, ST.wMinute, ST.wSecond)
End Function
Sub GetFTime(fName As String, Creation As Date, LastAccess As Date, LastWrite As Date)
Dim hFile As Long, ct As FileTime, at As FileTime, wt As FileTime
hFile = CreateFile(fName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
GetFileTime hFile, ct, at, wt
CloseHandle hFile
Creation = FTtoDT(ct): LastAccess = FTtoDT(at): LastWrite = FTtoDT(wt)
GlobCreationDate = FTtoDT(ct): GlobLastAccess = FTtoDT(at): GlobLastWrite = FTtoDT(wt)
End Sub
Sub SetFTime(fName As String, Optional Creation As Date = -657434, Optional LastAccess As Date = -657434, Optional LastWrite As Date = -657434)
Dim hFile As Long, ct As Date, at As Date, wt As Date
If Creation = -657434 Or LastAccess = -657434 Or LastWrite = -657434 Then
GetFTime fName, ct, at, wt
If Creation = -657434 Then Creation = ct
If LastAccess = -657434 Then LastAccess = at
If LastWrite = -657434 Then LastWrite = wt
End If
hFile = CreateFile(fName, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
SetFileTime hFile, DTtoFT(Creation), DTtoFT(LastAccess), DTtoFT(LastWrite)
CloseHandle hFile
End Sub
Sub SetChanges()
Dim T1 As Date, T2 As Date, T3 As Date, T4 As Date, T5 As Date, T6 As Date
Dim cn As Object, strQuery As String
Dim strPathToDB As String
FileAddress = "D:\Projects\DB1.accdb"
GetFTime FileAddress, T1, T2, T3
'some code right here
SetFTime FileAddress, T1, T2, T3
'
End Sub