Страницы: 1
RSS
Как изменять путь к внешнему файлу?
 
Суть проблемы:  
Некая программа формирует текстовый файл с интервалом в 5 минут и сохраняет его по такому пути – C:\Data\G\M\D\File.txt, где G – номер года (06, 07, 08…), М – номер месяца (01…12), D – номер дня (01…30[31]). Имя файла неизменное. В 00:00 новых суток в папке текущего месяца создается новый каталог с новым именем, соответствующим номеру новых суток, и там хранится тот самый, который я использую как внешний источник данных. На данный момент я (или мои коллеги) вынуждены каждый раз вручную переделывать запрос. Можно ли с помощью VBA эту операцию автоматизировать? Хотя бы в пределах одного месяца. Вижу примерно такое решение: извлечь номер дня из системной даты (это легко) и сформировать на основании номера сетевой путь, куда "присосаться". Но, ... не умею я это.
 
{quote}{login=Юрий М}{date=09.01.2008 09:53}{thema=Как изменять путь к внешнему файлу?}{post}Суть проблемы:  
Некая программа формирует текстовый файл с интервалом в 5 минут и сохраняет его по такому пути – C:\Data\G\M\D\File.txt, где G – номер года (06, 07, 08…), М – номер месяца (01…12), D – номер дня (01…30[31]). Имя файла неизменное. В 00:00 новых суток в папке текущего месяца создается новый каталог с новым именем, соответствующим номеру новых суток, и там хранится тот самый, который я использую как внешний источник данных. На данный момент я (или мои коллеги) вынуждены каждый раз вручную переделывать запрос. Можно ли с помощью VBA эту операцию автоматизировать? Хотя бы в пределах одного месяца. Вижу примерно такое решение: извлечь номер дня из системной даты (это легко) и сформировать на основании номера сетевой путь, куда "присосаться". Но, ... не умею я это.{/post}{/quote}
Попробуйте записать макрорекордером последовательность ваших действий по исправлению параметров запроса... и посмотрите результат... Если внимательно разобраться в нем, подставить в него необходимые доплонения не потребуют большого труда.
 
Записал макрорекордером запрос к двум разным файлам. Вижу разницу в пути к файлу. Но мне это ничего не дает. Как меянть этот путь - не знаю. Это я и так вручную делаю, а хочется использовать возможности VBA. "Лень толкает прогресс!"
 
Абсолютно правильный совет уже поступил (см. выше). Развиваю идею - если ты открываешь текстовые файлы EXCELем, в VBA-проекте (нажимаешь Alt+F11 из Excel) в дереве листов VBA есть лист "Эта книга". Открываешь его и на белом листе пишешь программку для СТАНДАРНОЙ процедуры EXCEL, именуемой Workbook_Open, которая выполняет описанные внутри нее команды ДО ОТКРЫТИЯ книги EXCEL. Остается внутрь нее поместить ту макрокоманду, которую рекомендовал предыдущий коллега (см. выше). Типа, должно получиться так:  
 
Sub МАКРОС()  
   ' этот пример - для импорта из другого файла EXCEL  
 
   L = "C:\Data\G\M\D\FileName77.xls"  
     
   With ActiveSheet.QueryTables.Add(Connection:=Array( _  
       "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Password="""";User ID=Admin;Data Source=" & L & ";Mode=Share Deny Write;" _  
       , _  
       "Extended Properties=""HDR=YES;"";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Database Password="""";Jet OLEDB:" _  
       , _  
       "Engine Type=35;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OL" _  
       , _  
       "EDB:New Database Password="""";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale" _  
       , _  
       " on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False" _  
       ), Destination:=Range("A1"))  
       .CommandType = xlCmdTable  
       .CommandText = Array("XA$XA")  ' именованный диапазон в EXCEL  
       .Name = "FileName77"  
       .FieldNames = True  
       .RowNumbers = False  
       .FillAdjacentFormulas = False  
       .PreserveFormatting = True  
       .RefreshOnFileOpen = False  
       .BackgroundQuery = True  
       .RefreshStyle = xlInsertDeleteCells  
       .SavePassword = False  
       .SaveData = True  
       .AdjustColumnWidth = True  
       .RefreshPeriod = 0  
       .PreserveColumnInfo = True  
       .SourceDataFile = L  
       .Refresh BackgroundQuery:=False  
   End With  
End Sub  
 
Поговори с программерами - пусть помогут.  
Таким образом EXCEL перед открытием текущего файла EXCEL определяет текущую дату, от нее - новый путь файла и в запросе (имеющем определенное имя) меняет строку подключения. Удачи!
 
Приношу извинения за допущенную ошибку - не оттуда скопировал текст макроса. Итак, правильный вариант:  
 
Private Sub Workbook_Open()  
 
L = "C:\Data\G\M\D\FileName77.xls"  
 
   With Selection.QueryTable  
       .Connection = Array( _  
       "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=" & L & ";Mode=Share Deny Write;Extended Pro" _  
       , _  
       "perties=""HDR=YES;"";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=35;Jet OLEDB:Database Locking M" _  
       , _  
       "ode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="""";Jet OLEDB:Crea" _  
       , _  
       "te System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without" _  
       , " Replica Repair=False;Jet OLEDB:SFP=False")  
       .CommandType = xlCmdTable  
       .CommandText = Array("XA$")  
       .Refresh BackgroundQuery:=False  
   End With  
End Sub  
 
Главное - разместить данный макрос на листе "Эта книга" в проекте VBA. Осталось перед второй строкой макроса (т.е. перед строкой "L=....") написать программку по определению текстовой строки адреса исходного файла.
 
Alexale, спасибо. Буду пробовать. Но, вроде, как я понял, этот код сработает при открытии моего файла-приемника (книги). Задача стоит иначе: мой файл-приемник.xls постоянно открыт и в 00:01 он должен автоматом перейти на прием данных от файл-источник.txt с тем же именем, но который уже находится в другом каталоге, имя которого на единицу больше того, с которым работали еще в 23:55. Вот такая задача. Вроде правильно сформулировал :-)
 
Для этой ситуации ЕСТЬ простейший и одновременно тупейший выход, но главной - он работает (проверено) с МИНИМАЛЬНЫМ применением макросов.  
У запросов EXCEL, размещенных на листе EXCEL, есть возможность настройки запроса - высвечивается небольшре окно с заголовком "Свойства внешнего диапазона". Например, в этом окне определяется ИМЯ диапазона и другие настройки. В этом окне есть строка "обновлять каждые ..." и стоит поле для ввода интервала в минутах. Выставляем, к примеру, 4 минут. Дальше наступает самое интересное и важное: в кодах EXCEL (в VBA-проекте) на листе теперь уже не "Эта книга", а на том, который соответствует вашему листу с запросом пишется следующий примитивный текст:  
 
Private Sub Worksheet_Change(ByVal Target As Range)  
 MsgBox Now()  
End Sub  
 
Теперь при АВТОМАТИЧЕСКОМ обновлении EXCEL-запроса через 5 минут ИЛИ по нажатии кнопки ОБНОВИТЬ ДАННЫЕ срабатывает указанная процедура Worksheet_Change и производится действие (в примере - на экран выводится текущая дата).  
Т.к. файл не закрывается, а открыт постоянно, EXCEL берет под свою ответственность еже-5-минутное обновдение запроса, следовательно, еже-5-минутное срабатывание процедуры Worksheet_Change и соответственно, когда вы вместо строки "MsgBox Now()" поместите текст переопределения строки подключения запроса (из моего второго послания), запрос обновиться уже с новым адресом. Думаю, это то, что вам и нужно. Еще раз удачи!
 
Alexale, спасибо, что пытаетесь мне помочь. Но я не вижу в присланном Вами коде строки, которую можно было бы истолковать так:  
ЕСЛИ время >= 00:01 ТО  
следует изменить путь C:\Data\G08\M01\D09\File.txt на C:\Data\G08\M01\D10\File.txt.  
Иначе C:\Data\G08\M01\D09\File.txt    
Как менять сам путь? Может я бестолково описываю задачу?
 
{quote}{login=Юрий М}{date=10.01.2008 02:15}{thema=}{post}Alexale, спасибо, что пытаетесь мне помочь. Но я не вижу в присланном Вами коде строки, которую можно было бы истолковать так:  
ЕСЛИ время >= 00:01 ТО  
следует изменить путь C:\Data\G08\M01\D09\File.txt на C:\Data\G08\M01\D10\File.txt.  
Иначе C:\Data\G08\M01\D09\File.txt    
Как менять сам путь? Может я бестолково описываю задачу?{/post}{/quote}  
В Excel есть такой метод OnTime, он позволяет поставить в очередь на запуск нужной процедуры в нужное время.  
Например,  
 
Application.OnTime DateSerial(2009,01,01)+TimeSerial(0,0,0), "MyMacro"  
 
установит, чтобы в полночь на 01/01/2009 запустился макрос MyMacro. Если до этого момента Excel не будет прекращать свою работу, то указанный макрос запустится в указанное время.  
 
Запускаемым по OnTime может быть любой макрос, в том числе и макрос запускающий этот OnTime:  
 
Sub MyMacro()  
Application.OnTime Now()+TimeSerial(1,0,0), "MyMacro"  
End Sub  
 
Запустив однажды такой макрос, он будет отрабатываться каждый час, пока Excel будет работать. А добавив к этому еще такой обработчик события:  
 
Sub Workbook_Open()  
Call MyMAcro  
End Sub  
 
получим периодический запуск макроса MyMacro автоматически по открытию файла.  
 
Далее... Допустим, что в переменной L находится начальное значение пути к файлу:  
 
L="C:\Temp\"  
 
К этому пути нужно добавить имя папки соответствующей номеру текущего года, и имя подпапки, соответствующей номеру текущего месяца, и имя файла, соответстсвующий номеру текущего дня. Пишем так:  
 
L = L & Year(Date()) & "\" & Month(Date()) & "\" & Day(Date()) & ".txt"  
 
И для 10/01/2008 получим в L следующий путь и имя файла:  
 
C:\Temp\2008\01\10.txt  
 
Итак осталось только соединить процедуры с OnTime с присвоением значения переменной L.  
 
В стандартном модуле процедур:  
 
Sub MyMacro()  
Dim L as String  
Application.OnTime Now()+TimeSerial(1,0,0), "MyMacro"  
L = "C:\Temp\" & Year(Date()) & "\" & Month(Date()) & "\" & Day(Date()) & ".txt"  
Debug.Print L  
End Sub  
 
В модуле книги:  
 
Sub Workbook_Open()  
Call MyMAcro  
End Sub  
 
Таким образом получим ежечасный запуск макроса MyMacro в котором переменной L присваивается путь и имя файла, соответствующие текущей дате.
 
Есть небольшое дополнение:  
Month(Date()) на текущий момент дает значение "1", а как я понял нужно значение "01"  
поэтому файл "найдется", если записать так:  
Format(Month(Date), "00")  
и аналогично для функции Day(Date)  
Format(Day(Date), "00")  
И скобки после Date() не нужны, просто Date. Впрочем vba их сам уберет.
 
{quote}{login=Лузер}{date=10.01.2008 08:38}{thema=}{post}Есть небольшое дополнение:  
Month(Date()) на текущий момент дает значение "1", а как я понял нужно значение "01"  
поэтому файл "найдется", если записать так:  
Format(Month(Date), "00")  
и аналогично для функции Day(Date)  
Format(Day(Date), "00")  
И скобки после Date() не нужны, просто Date. Впрочем vba их сам уберет.{/post}{/quote}  
Да, точно... написал все без проверки... поэтому и упустил.
 
Спасибо всем - буду тестировать
 
Ребята!    
А ведь мне нужно сформировать путь такого вида:  
C:\...\G08\M01\D10\File.txt.
 
L = "C:\...\G" & Format(Date, "yy") & "\M" & Format(Date, "mm") & "\D" & Format(Date, "dd") & "\File.txt"
 
Лузер, ты всегда приходишь на помощь. Спасибо
 
немного усложним задачу....  нужно подвязать макрос к такому пути:  
 
С:\tmp\12_20_13_15\  
 
где 12 месяц  
20 день    
13 час  
15 мин  
Фишка в том, что нужно чтобы цеплялись только месяц и день, а часы и минуты не важны, т.к. постоянно меняются....  
 
что то типа  
 
File Copy ("C:\tmp\" & Month & "_" & Day & "_" * " \ *.* ) , C:\destination\
Страницы: 1
Читают тему
Наверх