Страницы: 1
RSS
Как заархивировать файл rar-ом в VBA?
 
Т.е. после того как файл сохранён  
ActiveWorkbook.SaveAs Filename:= "C:\price" & Date & ".xlsx", FileFormat:= xlOpenXMLWorkbook, CreateBackup:=False  
хотелось бы его заархивировать, т.е. создать price.rar.  
Ну, а после вообще отправить его на ftp:\\site.ru\price\  
Как сделать это средствами VBA ума не приложу.
 
rar.exe поддерживает командную строку.  
Как именно Вы хотите заархивировать - читайте хелп к рару  
а в вба используйте функцию shell  
y=shell("rar.exe /какие-то ключи")  
с фтп соответственно:  
y=shell("ftp.exe /какие-то ключи")  
Возможно придется вставить задержку, пока рар будет делом занят. Или проверять наличие вновь созданного price.rar
Bite my shiny metal ass!      
 
{quote}{login=Лузер™}{date=13.02.2009 02:23}{thema=}{post} Или проверять наличие вновь созданного price.rar{/post}{/quote}  
Простите, а это как сделать?
 
Архивируем файл C:\Temp\Test 5.xls    
 
Sub Rar()    
'Архивируем файл C:\Temp\Test 5.xls    
   Dim RetVal    
   Dim WinRarApp$, iFileName$, iArhivName$, adr$, iPath$    
     
   WinRarApp$ = "C:\Program Files\WinRAR\WinRAR.exe a -ep -df "    
   ' a   - заархивировать    
   ' -ep   - исключить пути из имён    
   ' -ep1  - исключить базовую папку из пути    
   ' -df    - удалить файлы после архивации    
   iPath = "C:\Temp\"    
   iFileName$ = "Test 5.xls"    
   iArhivName$ = "Test 5.rar"    
   'добавляем двойные кавычки, что позволит нам работать с именем файла и путём, которые содержат пробелы.    
   'без кавычек пробелы недопустимы    
   adr$ = WinRarApp$ & " """ & iPath & iArhivName$ & """ """ & iPath & iFileName$ & """ "    
   RetVal = Shell(adr$, vbHide) 'vbNormalFocus)    
End Sub    
 
 
 
Разархивируем архив C:\Temp\Test 5.rar    
 
Sub UnRar()    
  'Разархивируем архив C:\Temp\Test 5.rar    
   WinRarApp$ = "C:\Program Files\WinRAR\WinRAR.exe e -o+"    
   ' e  - разархивировать    
   ' -o+  - перезаписывать существующие файлы    
   iPath = "C:\Temp\"    
   iArhivName$ = "Test 5.rar"    
   'добавляем двойные кавычки, что позволит нам работать с именем файла и путём, которые содержат пробелы.    
   'без кавычек пробелы недопустимы    
   adr$ = WinRarApp$ & " """ & iPath & iArhivName$ & """ """ & iPath & """ "    
   RetVal = Shell(adr$, vbHide)  'vbNormalFocus)    
End Sub
 
if dir("C:\price.rar") <>"" then msgbox "файл готов"  
Только надо посмотреть будет, может рар сразу создает price.rar, а потом его наполняет, тогда это бесполезно.  
Я в аналогичном случае смотрел лог проги, я знал, что когда прога отработает после вызова через shell, она себе в лог две строки пишет.  
вба считывал лог в массив, считал количество строк и сравнивал с количеством до запуска shell.
Bite my shiny metal ass!      
 
Ого. Как оперативно, спасИбо!
 
Option Explicit  
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF  
Const STILL_ACTIVE As Long = &H103  
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long  
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long  
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long  
Private appFocus As Long, appWaitInSecond As Long  
Public Property Let SetWaitInSecond(second As Long)  
   appWaitInSecond = IIf(second > 0, second, 0)  
End Property  
Public Property Let SetFocus(focus As Long)  
   If focus >= 0 And focus < 7 Then  
       appFocus = focus \ 1  
   Else  
       appFocus = vbNormalFocus  
   End If  
End Property  
 
Function Execute(fname As String) As Boolean  
Dim lExitCode As Long, hdlProg As Long, progID As Long, lastTime As Variant  
 
progID = Shell(fname, appFocus)  
hdlProg = OpenProcess(PROCESS_ALL_ACCESS, False, progID)  
lastTime = Now + TimeValue("0:00:" & appWaitInSecond)  
Do  
   If Now > lastTime And appWaitInSecond <> 0 Then  
       MsgBox "Превышено время ожидания", vbCritical  
       CloseHandle (hdlProg)  
       Execute = False  
       Exit Function  
   End If  
   DoEvents  
   GetExitCodeProcess hdlProg, lExitCode  
Loop While lExitCode = STILL_ACTIVE  
CloseHandle (hdlProg)  
Execute = True  
End Function  
 
Оформите как класс и будет вам счастье. Процедурка ждет завершения работы любого приложения, которое вызвали через shell
 
да, файл создается сразу, потом наполняется..  
(я правда 7.zip использовал - он бесплатен)  
я запускал батник с  двумя строками -  вызовом архиватора и создание файла индикатора(или запись в этот файл-индикатор флага выполнения)  
 
батник ждет, пока архиватор отработает..  а иксель ловит появление файла индикатора в цикле с doevents(если требуется фоновое исполнение)
Живи и дай жить..
 
А если у нас имеется папка с отчетами по регионам (допустим 26 файлов ексель) можно ли их всех запихнуть в один архив? Ну либо вызвать рар/зип уже над этим количеством файлов в котором останется ввести имя архива и нажать кнопку поехали?  
 
Или это удобнее сделать архивируя вышестоящую папку? В таком случае как создавать и именовать папки через ВБА?  
 
Можно ли в рар/зип передавать пароли, название архива, куда его разместить и степень сжатия?  
 
Спасибо.
 
Еще свой вариант. Не пропадать же.
Я сам - дурнее всякого примера! ...
 
{quote}{login=Jom}{date=13.02.2009 03:47}{thema=}{post}Option Explicit  
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF  
Const STILL_ACTIVE As Long = &H103  
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long  
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long  
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long  
Private appFocus As Long, appWaitInSecond As Long  
Public Property Let SetWaitInSecond(second As Long)  
   appWaitInSecond = IIf(second > 0, second, 0)  
End Property  
Public Property Let SetFocus(focus As Long)  
   If focus >= 0 And focus < 7 Then  
       appFocus = focus \ 1  
   Else  
       appFocus = vbNormalFocus  
   End If  
End Property  
 
Function Execute(fname As String) As Boolean  
Dim lExitCode As Long, hdlProg As Long, progID As Long, lastTime As Variant  
 
progID = Shell(fname, appFocus)  
hdlProg = OpenProcess(PROCESS_ALL_ACCESS, False, progID)  
lastTime = Now + TimeValue("0:00:" & appWaitInSecond)  
Do  
   If Now > lastTime And appWaitInSecond <> 0 Then  
       MsgBox "Превышено время ожидания", vbCritical  
       CloseHandle (hdlProg)  
       Execute = False  
       Exit Function  
   End If  
   DoEvents  
   GetExitCodeProcess hdlProg, lExitCode  
Loop While lExitCode = STILL_ACTIVE  
CloseHandle (hdlProg)  
Execute = True  
End Function  
 
Оформите как класс и будет вам счастье. Процедурка ждет завершения работы любого приложения, которое вызвали через shell{/post}{/quote}  
Самое верное и надежное решение.  
Работает.
Страницы: 1
Читают тему
Наверх