2013-08-14 2 views
1

Я пишу программу, которая интегрируется с сканером ScanSnap. Сканеры ScanSnap не поддерживают TWAIN. После сканирования документа он автоматически сохраняется в формате PDF.Получить уведомление о создании файла в VBA без опроса

Я хочу отслеживать каталог, в котором файлы будут сохранены, и предпринять некоторые действия, когда файл появится (и все будет записано). Простым подходом является использование события Timer формы доступа MS Access и проверка существующего файла за небольшой промежуток времени.

Есть ли более эффективная альтернатива через Windows Messaging, FileSystemObject или некоторую функцию Windows API, которая поддерживает обратные вызовы?

+0

Вы можете использовать vbs с FileSystemObject, чтобы отслеживать конкретную папку для изменений файла, сравнивать с именами файлов в отдельном текстовом файле/файле Excel. Затем напишите новые данные файла. Но для этого понадобится оболочка, работающая в фоновом режиме. – PatricK

ответ

1

Ничего в Excel.

Вы можете создать другое приложение, которое контролирует файловую систему, и выполняет макрос Excel, открывая книгу при необходимости, при необходимости открывая Excel.

+0

Это мысль. Я на самом деле делаю это в MS Access, но будут применяться те же концепции. У события таймера есть некоторые раздражающие [побочные эффекты] (http://stackoverflow.com/a/10900069/154439), но я думаю, что я бы лучше разобрался с теми, кто был в моем конкретном случае. – mwolfe02

+0

Обычно такие задания могут выполняться в фоновом режиме и не требуют какого-либо интерфейса. Обычно я делаю приложение vb, которое создает свой собственный скрытый экземпляр Excel, поэтому нет конфликтов с каким-либо интерактивным экземпляром. – stenci

+0

В моем конкретном случае мне нужно интегрировать функциональность с пользовательским интерфейсом. Но ваш подход, безусловно, имеет свои достоинства и может быть более полезным для будущих пользователей, которые спотыкаются на этот вопрос. – mwolfe02

1

@Steve эффективно ответил на вопрос, который я задал. Я должен был спросить, как контролировать изменения файловой системы в потоке, отдельно от потока пользовательского интерфейса MS Access. И простой ответ на этот вопрос: VBA does not support multi-threading в Office applications.

Существует множество способов обхода, которые обычно включают вызов внешней библиотеки COM или integrating with an external application. Я решил, что ни один из них не был очень привлекательным, и вместо этого решил реализовать решение в VB.Net, используя класс FileSystemWatcher.

0

Не уверен, что это действительно решает вашу проблему, но вот подход с использованием Excel VBA, который помог мне контролировать конкретный файл в определенной папке и выполнять определенные действия (здесь: скопировать файл в другую папку), если файл изменено и сохранен (т.е. когда метки времени изменения файла):

Option Explicit 

Const SourcePath = "C:\YourFolder\" 
Const TargetPath = "C:\YourFolder\YourFolder_Changes\" 
Const TargetFile = "YourFileName" 

Private m_blnLooping As Boolean 

Private Sub CommandButton1_Click() 

Dim FSO As Scripting.FileSystemObject 
Dim n, msg, dt, inttext As String 
Dim file, files As Object 
Dim d1, d2 As Date 
Dim cnt As Integer 
Dim wsshell 

Application.ScreenUpdating = False 
On Error Resume Next 

Set FSO = CreateObject("Scripting.FileSystemObject") 
Set files = FSO.GetFolder(SourcePath).files 
Set wsshell = CreateObject("WScript.Shell") 

msg = "FileWatcher started. Monitoring of " & TargetFile & " in progress." 
cnt = 0 

'Initialize: Loop through Folder content and get file date 
For Each file In files 
    n = file.name 
    'Get Initial SaveDate of Target File 
    If n = TargetFile Then 
     d1 = file.DateLastModified 
    End If 
Next file 

m_blnLooping = True 

inttext = wsshell.popup(msg, 2, "FileWatcher Ready", vbInformation) 
'Message Box should close after 2 seconds automatically 

Shell "C:\WINDOWS\explorer.exe """ & TargetPath & "", vbNormalFocus 
'Open Windows Explorer and display Target Directory to see changes 

Do While m_blnLooping 
    For Each file In files 
     n = file.name 
     If n = TargetFile Then 
      d2 = file.DateLastModified 
      If d2 > d1 Then 
       dt = Format(CStr(Now), "yyyy-mm-dd_hh-mm-ss") 
       'FSO.CopyFile (SourcePath & TargetFile), (TargetPath & Left(TargetFile, Len(TargetFile) - 4) & "_" & dt & ".txt"), True 'Option with file name extension 
       FSO.CopyFile (SourcePath & TargetFile), (TargetPath & TargetFile & "_" & dt), True          'Option without file name extension 
       cnt = cnt + 1 
       d1 = d2 
      End If 
     End If 
    Next file 
    'Application.Wait (Now() + CDate("00:00:02")) 'wait 2 seconds, then loop again 
DoEvents 
Loop 

msg = "File " & TargetFile & " has been updated " & cnt & " times." 
inttext = wsshell.popup(msg, 2, "FileWatcher Closed", vbInformation) 
'Message Box should close after 2 seconds automatically 

Application.ScreenUpdating = True 

End Sub 

Private Sub CommandButton2_Click() 

m_blnLooping = False 

End Sub 

процедура активируется через CommandButton («СТАРТ») и не перебирает два заданной папку (держит смотреть файл) до другого CommandButton («STOP»). Тем не менее, вы можете настроить код для мониторинга создания файла вместо изменений файла (файл.DateCreated вместо file.DateLastModified). Код предназначен только для того, чтобы дать вам подсказку, которая может решить вашу проблему.

+0

Я ценю время, когда вы вписываете свой ответ. Используемая вами методика - это опрос (т. Е. Многократная проверка состояния файла). Я специально пытался избежать этого подхода, потому что это излишне интенсивно работа процессора и ввода-вывода. Кроме того, он не позволяет запускать другой код. – mwolfe02