powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / автоматизация
24 сообщений из 24, страница 1 из 1
автоматизация
    #36279278
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день.Есть макрос.

Sub Ìàêðîñ1()
'
' Ìàêðîñ1 Ìàêðîñ
'
' Ñî÷åòàíèå êëàâèø: Ctrl+a
'
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;C:\Users\путь\путь\путь\папка в которой файлы txt\01010901.txt", Destination:= _
Range("$A$1"))
.Name = "01010901"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 1251
.TextFileStartRow = 1
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.TextFileColumnDataTypes = Array(1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
End Sub

Макрос делает экспорт txt файла на 1 лист.Подскажите как макрос доработать,что бы он брал следующий файл в папке(пока файлы не кончатся) и делал тот же самый экспорт на следующий лист.
...
Рейтинг: 0 / 0
автоматизация
    #36279439
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начинает копировать со второго файла в папке. Первый можна скопировать если просто разместить Ваш код перед моим.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
Sub CopyAll()
Dim mypath As String
Dim MyFileName As String

mypath = "D:\"
MyFileName = Dir(mypath + "*.txt")
On Error Resume Next
Do Until MyFileName = ""
MyFileName = Dir
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & mypath & MyFileName, Destination:= _
Range("$A$1"))
.Name = "01010901"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod =  0 
.TextFilePromptOnRefresh = False
.TextFilePlatform =  1251 
.TextFileStartRow =  1 
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.TextFileColumnDataTypes = Array( 1 )
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
Sheets(ActiveSheet.Index +  1 ).Activate
Loop

End Sub
...
Рейтинг: 0 / 0
автоматизация
    #36279813
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Спасибо большее.Можно еще вопрос.Сейчас макрос все это дело шлепает на один лист.
Мне необходимо,что шлепал по след условию.
Макрос берет файл из папки и обрабатывает его след образом.
1.Открывает файл и проверяет значение РД=Значение Пример:РД=01 1
Если это 01 1 значит на экспортирует 1 лист.
Если это 02 2 значит на экспортирует 2 лист.
Если это 03 3 значит на экспортирует 3 лист.
Если это 80 80 значит на 4 лист.
После чего экспортирует данный файл в лист по выше указанному условию.
...
Рейтинг: 0 / 0
автоматизация
    #36279839
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
crystalreportsСейчас макрос все это дело шлепает на один лист.
Мне необходимо,что шлепал по след условию.
Макрос берет файл из папки и обрабатывает его след образом.
1.Открывает файл и проверяет значение РД=Значение Пример:РД=01 1
Если это 01 1 значит на экспортирует 1 лист.
Если это 02 2 значит на экспортирует 2 лист.
Если это 03 3 значит на экспортирует 3 лист.
Если это 80 80 значит на 4 лист.
Странно, что на один... Вроде должен активировать следующий лист:
Код: plaintext
Sheets(ActiveSheet.Index +  1 ).Activate
Что такое РД ?
Вложите пример текстового файла (на несколько строк, с этим РД).
...
Рейтинг: 0 / 0
автоматизация
    #36279886
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Не все шлепает на 1 лист не смотря на Sheets(ActiveSheet.Index + 1).Activate.
...
Рейтинг: 0 / 0
автоматизация
    #36280203
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот такое пробуйте:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
Sub newTry()
Dim fso, f, f1, fc, txs
Dim mypath As String
Dim s As String
    
mypath = "D:\mytxt\"
        
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(mypath)
Set fc = f.Files
    
For Each f1 In fc
    Set txs = f1.OpenAsTextStream( 1 )
    s = txs.ReadAll
    txs.Close
    
    Select Case Right(Mid(s, InStr( 1 , s, "РД="),  5 ),  2 )
    Case "01"
    Sheets("Лист1").Select
    Case "02"
    Sheets("Лист2").Select
    Case "03"
    Sheets("Лист3").Select
    Case "80"
    Sheets("Лист4").Select
    End Select
    
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & mypath & f1.Name, Destination:= _
Range("$A$1"))
.Name = "01010901"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod =  0 
.TextFilePromptOnRefresh = False
.TextFilePlatform =  1251 
.TextFileStartRow =  1 
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.TextFileColumnDataTypes = Array( 1 )
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With

Next

End Sub
...
Рейтинг: 0 / 0
автоматизация
    #36281536
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G спасибо большее за помощь.
...
Рейтинг: 0 / 0
автоматизация
    #36282465
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

При экспорте данные из txt файла становятся рядом в ряд.
Вопрос: Можно,что бы между ними было 7 пустых столбиков
Пример: Данные из 1 файла - 7 пустых столбиков - 2 файл - 7 пустых столбиков ...
...
Рейтинг: 0 / 0
автоматизация
    #36282579
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТСПри экспорте данные из txt файла становятся рядом в ряд.
Вопрос: Можно,что бы между ними было 7 пустых столбиков
Пример: Данные из 1 файла - 7 пустых столбиков - 2 файл - 7 пустых столбиков ...
Не понял, что опять данные копируются на один лист? И про какие данные Вы говорите, уточните, а то не понятно, либо же опять илюстрированный пример выложите...
...
Рейтинг: 0 / 0
автоматизация
    #36282612
Hugo121
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извините, я тут тоже заинтересовался - никогда кодом query не вставлял на лист, пригодится...

crystalreports
Вопрос: Можно,что бы между ними было 7 пустых столбиков
Пример: Данные из 1 файла - 7 пустых столбиков - 2 файл - 7 пустых столбиков ...

Так работает (кусок кода):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
       End Select
    
 Range("$A$1").Select
 
    Selection.EntireColumn.Insert
    Selection.EntireColumn.Insert
    Selection.EntireColumn.Insert
    Selection.EntireColumn.Insert
    Selection.EntireColumn.Insert
    Selection.EntireColumn.Insert
    Selection.EntireColumn.Insert
       
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & mypath & f1.Name, Destination:= _

Новые данные вставляются в А1 (так в основном коде прописано), старые сдвигаются вправо. Поэтому наверное можно сперва добавить нужное количество столбцов.

MaximuS_G Не понял, что опять данные копируются на один лист? - это если несколько раз подряд код запускать на одном файле.
...
Рейтинг: 0 / 0
автоматизация
    #36282692
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hugo121 - это если несколько раз подряд код запускать на одном файле.
А, ясно. Спасибо. Как-то не подумал :)...

Hugo121 Selection.EntireColumn.Insert
Selection.EntireColumn.Insert
Selection.EntireColumn.Insert
Selection.EntireColumn.Insert
Selection.EntireColumn.Insert
Selection.EntireColumn.Insert
Selection.EntireColumn.Insert

А так? Может быстрее:
Код: plaintext
1.
    Columns("A:G").Select
    Selection.Insert Shift:=xlToRight
или через цикл...
...
Рейтинг: 0 / 0
автоматизация
    #36282716
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Нет ваш код работаем отлично.Данные грузятся на ура.
Если можно помогите с другим макросом но в тужу печку.
...
Рейтинг: 0 / 0
автоматизация
    #36282775
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давайте уточним, правильно ли я Вас понял...
1) Запустите один раз макрос (что бы данные вставились один раз)
2) Скопируйте эти данные
3) Вставьте на новый лист следующим образом: Специальная вставка - Галочки: Транспортировать и Значения.

Это то, что я понимаю идеальный вариант, только еще нужно скопировать вниз первую строку (содержащую общую информацию) ? Если да, то макросом можно каждый раз данные из листа доставки переносить в лист сборщик, при этом переварачивая их как я указал.
...
Рейтинг: 0 / 0
автоматизация
    #36282819
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximuS_G,

Немного не так.
...
Рейтинг: 0 / 0
автоматизация
    #36282893
Hugo121
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может быть, раз уж такие сложности, сразу считывать файлы в массив данных, и затем выгружать его на лист в нужном порядке?
И делать это можно vbs-скриптом - запустили скрипт, указали (если жёстко не прописано в коде) какую папку обрабатывать и куда класть данные, получили готовый файл.
Результат может быть после одного клика, и экселевский файл без макроса внутри (хотя конечно макрос можно держать и в другом файле).
Я бы так попробовал сделать, правда не факт, что реализацию будет проще сделать. И вот с xlsx (если это важно) не знаю, как в vbs обращаться.
...
Рейтинг: 0 / 0
автоматизация
    #36282954
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообщем создаете дополнительные листы:
Лист1_Converted, Лист2_Converted...
Номера строк, колонок уже сами подрегулируете.

Вот новый код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
Sub newTry()
Dim fso, f, f1, fc, txs
Dim mypath As String
Dim s As String
Dim r As Integer, r1 As Integer
    
mypath = "D:\mytxt\"
        
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(mypath)
Set fc = f.Files
    
For Each f1 In fc
    Set txs = f1.OpenAsTextStream( 1 )
    s = txs.ReadAll
    txs.Close
    
    Select Case Right(Mid(s, InStr( 1 , s, "РД="),  5 ),  2 )
    Case "01"
    Sheets("Лист1").Select
    Case "02"
    Sheets("Лист2").Select
    Case "03"
    Sheets("Лист3").Select
    Case "80"
    Sheets("Лист4").Select
    End Select
    
ActiveSheet.Cells.Clear
    
With ActiveSheet.QueryTables.Add(Connection:= _
"TEXT;" & mypath & f1.Name, Destination:= _
Range("$A$1"))
.Name = "01010901"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod =  0 
.TextFilePromptOnRefresh = False
.TextFilePlatform =  1251 
.TextFileStartRow =  1 
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = False
.TextFileSpaceDelimiter = False
.TextFileOtherDelimiter = "|"
.TextFileColumnDataTypes = Array( 1 )
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With

ActiveSheet.Range(Cells( 11 ,  1 ), Cells(Cells( 11 ,  1 ).End(xlDown).Row,  5 )).Copy
Sheets(ActiveSheet.Name & "_Converted").Cells( 1 ,  11 ).End(xlDown).Offset( 1 ,  0 ).PasteSpecial xlPasteValues, , , True
ActiveSheet.[a1:a10].Copy
Sheets(ActiveSheet.Name & "_Converted").Cells( 1 ,  1 ).End(xlDown).Offset( 1 ,  0 ).PasteSpecial xlPasteValues, , , True

Sheets(ActiveSheet.Name & "_Converted").Select
r = ActiveSheet.Cells( 1 ,  1 ).End(xlDown).Row
r1 = ActiveSheet.Cells( 1 ,  11 ).End(xlDown).Row
Selection.AutoFill Destination:=Range(Cells(r,  1 ), Cells(r1,  10 ))

Next

End Sub
...
Рейтинг: 0 / 0
автоматизация
    #36282957
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может действительно, как говорит Hugo121 подумать над чем нибудь другим в плане обработки данных.
...
Рейтинг: 0 / 0
автоматизация
    #36284603
Hugo121
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Например так - начало взял от MaximuS_G, немного добавил проверок на расширение и на наличие файлов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
'################################################################
'скрипт рассчитан на обработку текстовых файлов из c:\temp\mytxt\
'там же должен быть Test.xls, куда будут помещаться результаты
'################################################################

Dim fso, f, f1, fc, txs
Dim mypath' As String
Dim s' As String
Dim Dt()

t = Timer
    
mypath = "c:\temp\mytxt\"
        
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(mypath)
Set fc = f.Files
	if fc.count >  0  then
		Set objfullExcel = CreateObject("Excel.Application"): Set wb = objfullExcel.Workbooks.Open (mypath & "\Test.xls", Readonly = False)
	else
		Wscript.Quit
	end if

For Each f1 In fc
If UCase(fso.GetExtensionName(f1.Path)) = "TXT" Then

    Set txs = f1.OpenAsTextStream( 1 )
    s = txs.ReadAll
    txs.Close
    s = Replace(s, vbtab, "|")  'меняем vbtab, было условие в query
	arrLineList = Split(s , vbNewLine) 'массив всех строк, начало с 0

ReDim Preserve Dt(UBound(arrLineList), 4 )'устанавливаем размерность массива по числу строк, 5 элементов в строке (так в примере)

 for y =  0  to UBound(arrLineList)
 temp = Split(arrLineList(y) , "|")
  for yy =  0  to UBound(temp)
	Dt(y,yy) = temp(yy)
  next
 next

   Select Case Right(Mid(s, InStr( 1 , s, "РД="),  5 ),  2 )
    Case "01"
	Set objExcel = wb.Worksheets( 1 ): inexcel
	Erase Dt
    Case "02"
	Set objExcel = wb.Worksheets( 2 ): inexcel
	Erase Dt
    Case "03"
	Set objExcel = wb.Worksheets( 3 ): inexcel
	Erase Dt
    Case "80"
	Set objExcel = wb.Worksheets( 4 ): inexcel
	Erase Dt
   End Select
End If	
next

objfullExcel.Visible = True

t = Timer - t
msgbox "OK! Run in " & t

Wscript.Quit

Sub inexcel()

cnt = objExcel.UsedRange.rows.count: if cnt =  1  then cnt =  0  ' для начала файла сбрасываем в 0
' есть недочёт - UsedRange должна быть с первой строки листа
' Cells.SpecialCells(xlCellTypeLastCell).Row заставить работать из стороннего скрипта не получилось

 for x =  0  to UBound(Dt)
  for y =  0  to UBound(Dt, 2 )
  if Dt(x, 1 ) = Empty then
 	objExcel.Cells(cnt +  1 , x + y +  1 ).Value = Dt(x,y) 
  Else
	objExcel.Cells(cnt + y +  1 , x +  1 ).Value = Dt(x,y)
  End if
  next
next

End Sub
...
Рейтинг: 0 / 0
автоматизация
    #36284866
Hugo121
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так, в первой версии обнаружились косяки: если данных было на одну строку, то при повторном запуске они затирались.
Короче, трудно сделать корректное определение строки, куда надо писать - UsedRange.Rows.Count на пустом листе или листе с одной заполненной строкой даёт 1, и найти, как это отличить, мне не удаётся. Определить кодом, есть ли данные в первой строке, не получается.
Пока примем, что первая строка заполнена. Туда можно поставить заглавие до работы скрипта или после.
Ещё была ошибка, если текстовый файл не подходил ни под одну категорию (необнулялся массив), ну и мелочь с добавлением и названием листов, если их изначально меньше 4-х. Не получается добавить новый лист в конец списка (add :=after не работает в vbs, надо как-то иначе, но вот как?). Поэтому теперь к листам обращаюсь по имени, рассчитано на русский Эксель (иначе путаница с номерами и названиями листов).
Прикладываю новую версию, код почти как и раньше, если интересно, смотрите в файле.
Итого - желательно сперва заготовить чистый (или уже пользованный) файл с 4-мя листами с заголовками в первой строке, названными, как в коде.
Ну и как , расположение данных подходит или иначе надо?
Строку кода ReDim Preserve Dt(UBound(arrLineList),4) подправьте под задачу - вместо 4 ставьте количество столбцов данных - 1
...
Рейтинг: 0 / 0
автоматизация
    #36285282
MaximuS_G
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 crystalreports ,
Если все же будете брать мой код, заполните первые две строки в каждом из листов (Лист1_ Converted , Лист2_ Converted ...) до 20й колонки любыми значениями. Это что бы правильно определило первый раз куда вставлять транспортируемые данные. Когда будут добавлены другие записи, первые 2 строки можно удалить.
...
Рейтинг: 0 / 0
автоматизация
    #36287463
Hugo121
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 crystalreports, всё же мне кажется, данные надо иначе располагать. Оказалось не так просто, как я рассчитывал, но вроде работает.
Да, последнюю строку из предыдущего сообщения читать так: вместо 4 ставьте (количество_столбцов_данных - 1)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
'################################################################
'скрипт рассчитан на обработку текстовых файлов из c:\temp\mytxt\
'там же должен быть Test.xls, куда будут помещаться результаты
'################################################################

Dim fso, f, f1, fc, txs
Dim mypath
Dim s
Dim Dt()
Public cnt
Public x
Public xx
Public y

t = Timer
    
mypath = "c:\temp\mytxt\"
        
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFolder(mypath)
Set fc = f.Files
	if fc.count >  0  then
		Set objfullExcel = CreateObject("Excel.Application"): Set wb = objfullExcel.Workbooks.Open (mypath & "\Test.xls", ReadOnly = False)
		Do
		if wb.Sheets.Count <  4  then wb.Sheets(wb.Sheets.Count).Select: wb.Sheets.Add
		Loop Until wb.Sheets.Count =  4 
	else
		Wscript.Quit
	end if

For Each f1 In fc
If UCase(fso.GetExtensionName(f1.Path)) = "TXT" Then

    Set txs = f1.OpenAsTextStream( 1 )
    s = txs.ReadAll
    txs.Close
    s = Replace(s, vbtab, "|")  'меняем vbtab, было условие в query
	arrLineList = Split(s , vbNewLine) 'массив всех строк, начало с 0

ReDim Preserve Dt(UBound(arrLineList), 4 )'устанавливаем размерность массива по числу строк, 5 элементов в строке (так в примере)

	Select Case Right(Mid(s, InStr( 1 , s, "РД="),  5 ),  2 )
    Case "01"
	Set objExcel = wb.Worksheets("Лист1"): inexcel
	Erase Dt
    Case "02"
	Set objExcel = wb.Worksheets("Лист2"): inexcel
	Erase Dt
    Case "03"
	Set objExcel = wb.Worksheets("Лист3"): inexcel
	Erase Dt
    Case "80"
	Set objExcel = wb.Worksheets("Лист4"): inexcel
	Erase Dt
	Case Else
	Erase Dt	
  End Select
End If	
next

objfullExcel.Visible = True

Erase arrLineList
Set fso = Nothing
Set f = Nothing
Set fc = Nothing
Set txs = Nothing
Set s = Nothing
Set objfullExcel = Nothing
Set objExcel = Nothing

t = Timer - t
msgbox "OK! Run in " & t

Wscript.Quit

Sub inexcel()

 for y =  0  to UBound(arrLineList)
 temp = Split(arrLineList(y) , "|")
  for yy =  0  to UBound(temp)
	Dt(y,yy) = temp(yy)
  next
 next

cnt = objExcel.UsedRange.Row + objExcel.UsedRange.Rows.Count 'первая строка в любом случае считается заполненной!
'её можно позже или до начала работы скрипта заполнить заглавием.

 for x =  0  to UBound(Dt)
  for y =  0  to UBound(Dt, 2 )
  if Dt(x, 1 ) = Empty Then objExcel.Cells(cnt, x + y +  1 ).Value = Dt(x,y): xx = x
  if Dt(x, 1 ) <> Empty Then putdata : Exit For 
  next
next

End Sub

Sub putdata()

for z =  0  to UBound(Dt, 2 )
objExcel.Cells(cnt, xx + z +  2 ).Value = Dt(x,z)
next
cnt = objExcel.UsedRange.Row + objExcel.UsedRange.Rows.Count

End Sub
...
Рейтинг: 0 / 0
автоматизация
    #36386365
Фотография crystalreports
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hugo121, MaximuS_G

Спасибо вам за помощь!!С наступающим.
...
Рейтинг: 0 / 0
автоматизация
    #36395524
Hugo121
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С Новым Годом!
Раз уж тут рассмотрено два варианта разбора текста для Экселя,
решил добавить третий вариант - переносим vbs скрипт в макрос Экселя.
Делал на днях подарок бухгалтершам к Новому Году - оказывается, они каждый день
вдвоём тратят кучу времени и нервов, выбирая из распечатанного на несколькихх листах текстовика,
который выдаёт система, данные (много чисел, выборочно из кучи ненужной информации,
подчёркивая нужное по линеечке), которые плюсуют на калькуляторе в много сумм, которые затем заносят
в несколько форм в Экселе и распечатывают. Не понимаю, зачем это вообще нужно делать, но наверное нужно....
Мне кажется, это довольно типичная задача, поэтому если это эссе в итоге в Новом Году поможет ещё
хоть паре других бухгалтерш, я думаю стоит его написать :)
Конечно, давно уже надо было хотя бы сперва импортнуть этот текст в Excel (стандартная таблица,
легко переносится, расположение данных постоянно, можно разбивать по пробелам или фиксированно),
и затем его обрабатывать, всё легче, чем из текста выколупывать.
Но мне кажется, так кода нужно больше писать, чем если разбирать текст в vbs, поэтому я сперва
написал программу в vbs. Т.к. формы генерить из скрипта сложновато (различные рамки и форматирование,
все немного различаются), я решил закидывать полученные данные в уже готовый *.xls (сперва их
было много, соответсвенно на каждую по скрипту, всего несколько*2 файлов :) ). Но на практике
неудобно, что код привязан к определённому названию и расположению этих форм.
Да и вносить изменения сложно в много скриптов.
Если бы эти формы далее надо было пересылать другим людям, наверное я так бы и оставил - в формах
макросов нет, при открытии файла никаких вопросов, ну и т.д.
Но так как требуется всего лишь несколько раз распечатать несколько заполненных форм, я решил всю программу
и все формы объединить в одном файле. Т.к. текстовик генерится всегда в "c:\temp\Journal_" & ddd & ".txt",
где ddd - это день года (т.е. даже исходный текстовый файл выбирать приходится только если нет
сегодняшнего), теперь вся работа бухгалтерши (уже любой из отдела и одной) по этой задаче сводится к
открытию файла, разрешению макросов (или обновления данных) и нажатии в форме кнопки "Печатать"
Ещё в форме есть индивидуальный выбор форм для печати и отказ от печати. (Код формы можно посмотреть
в приложении, там сокращённый рабочий вариант всего, текстовый файл поместить в c:\temp\)
Единственная опасность - если вдруг изменится формат текстовика (сдвинутся в строках данные, слова-ориентиры
поменяются или десятичный разделитель заменят), тогда всё рухнет. На этот случай пришлось договариваться
с обслугой той системы, что они введут в начале первой строки версию файла - если она изменится, код работать
перестанет, и мне придётся смотреть, что изменилось и править код. Но это судя по всему бывает крайне редко.
Короче - привожу коротенько сокращённый код (оригинал ~ 600 строк), постарался прокомментировать для начинающих,
код получился несложный и его легко изменить для других задач.
Текстовый файл читается построчно, в строке (если в начале нужное слово) в определённых местах находятся
данные, они суммируются в переменных, затем выгружаются в формы.
В данной задаче не нужно скакать по файлу вверх-вниз, поэтому всё просто. В другой задаче я сперва читал всё
содержимое файла в многомерный массив, и затем обрабатывал элементы массива. Там код посложнее получался.
Т.к. я не профессионал от программирования, возможно в коде есть некоторые погрешности, если есть замечания,
говорите :)
Перенос кода из vbs в модуль xls прошёл практически без изменений кода, только Wscript.Quit заменил на Exit Sub,
и добавил типы переменным (в vbs они без указания типов).
Можно вместо Double использовать Currency, но тогда в ячейки сумма заносится с форматированием в виде валюты,
что мне в данном случае не надо, а переделывать формат - лишняя работа.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
Option Explicit
Sub Auto_Open()
If MsgBox("Update?", vbExclamation + vbOKCancel, "Warning!") = vbOK Then update 'если уровень безопасности низкий
'update 'если уровень безопасности средний
UserForm1.Show 'в форме настройки печати результатов
End Sub

Sub update()
'# определяем переменные, необязательно, но крайне желательно
Dim objFSO As Object, objDialog As Object, objTextFile As Object, strText$, strNextLine$
Dim ddd$, linecount As Long, dt As Date, versija$
Dim oms_eur_acc$, oms_usd_acc$
Dim oms_eur_res As Double, oms_eur_nres As Double, oms_eur_es As Double
Dim oms_usd_res As Double, oms_usd_nres As Double, oms_usd_es As Double
Dim intResult As Boolean
Dim oReg As Object, strKeyPath$, strValue$, strValueName$
Dim objExcel As Object

ddd = DatePart("y", Now()) 'определяем значение сегодняшнего ddd - если ddd в названии файла генерится без ведущих нулей
'ddd = Right(("00" & DatePart("y", Now())), 3) 'определяем значение сегодняшнего ddd - если ddd генерится с ведущими нулями - 3 цифры

Set objFSO = CreateObject("Scripting.FileSystemObject")
' если есть сегодняшний файл, сразу открываем его, если нет, предлагаем
' выбрать любой другой, можно отказаться и выйти из кода
If objFSO.FileExists("c:\temp\Journal_" & ddd & ".txt") Then
   Set objTextFile = objFSO.OpenTextFile("c:\temp\Journal_" & ddd & ".txt",  1 )
Else
   '# Диалог открытия файла
   Set objDialog = CreateObject("UserAccounts.CommonDialog")
   objDialog.Filter = "Journal Files|Journal_*.txt|All Files|*.*"
   objDialog.FilterIndex =  1 
   objDialog.InitialDir = "c:\temp\"
   intResult = objDialog.ShowOpen
   If intResult =  0  Then Exit Sub
   Const ForReading =  1 
   Set objTextFile = objFSO.OpenTextFile(objDialog.Filename, ForReading)
End If

'### определяем системный разделитель дробной части, это если в системе того, кто будет считать,
'    разделитель не точка, как в текстовике
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
strKeyPath = "Control Panel\International"
strValueName = "sDecimal"
oReg.GetExpandedStringValue &H80000001, strKeyPath, strValueName, strValue 'вот этот strValue нам и нужен
'###

linecount =  0 

Do Until objTextFile.AtEndOfStream 'пока не кончился файл
  strNextLine = objTextFile.Readline 'читаем посторочно
  linecount = linecount +  1  'счётчик строк
  'из первой строки файла читаем дату отчёта и версию, вместо "V.20091201" поставить текущее значение первых 10 символов строки
  If linecount =  1  Then dt = CDate(Mid(strNextLine,  68 ,  10 )): versija = Left(strNextLine,  10 ): If versija <> "V.20091201" Then MsgBox "New Version!" & vbNewLine & "Exit!!!", vbCritical: Exit Sub

  strNextLine = Replace(strNextLine, ".", strValue)  'меняем "." на системный разделитель дробной части
  
 If Left(strNextLine,  3 ) = "sum" Then Exit Do ' выход если кончилась значимая область (читаем до слова "sum", хотя можно читать
                                              ' и до конца файла, но незачем )

 Select Case Trim(Left(strNextLine,  16 ))'ищем знакомые слова, в данном случае "Test Word EUR" или "Test Word USD"
   Case "Test Word EUR"
      oms_eur_acc = Trim(Mid(strNextLine,  27 ,  13 ))' это значение суммировать не надо, и оно всегда постоянно в данной задаче
      oms_eur_res = oms_eur_res + CDbl(Trim(Mid(strNextLine,  70 ,  9 )))
      oms_eur_nres = oms_eur_nres + CDbl(Trim(Mid(strNextLine,  80 ,  9 )))
      oms_eur_es = oms_eur_es + CDbl(Trim(Mid(strNextLine,  90 ,  9 )))
   Case "Test Word USD"
      oms_usd_acc = Trim(Mid(strNextLine,  27 ,  13 ))' это значение суммировать не надо, и оно всегда постоянно в данной задаче
      oms_usd_res = oms_usd_res + CDbl(Trim(Mid(strNextLine,  70 ,  9 )))
      oms_usd_nres = oms_usd_nres + CDbl(Trim(Mid(strNextLine,  80 ,  9 )))
      oms_usd_es = oms_usd_es + CDbl(Trim(Mid(strNextLine,  90 ,  9 )))
' Таких циклов сделать столько, сколько различных значений надо найти и посчитать
 End Select
 
Loop 'читаем следующую строку

objTextFile.Close 'всё прочитано, закрываем текстовый файл

'Заносим данные в уже готовые формы
'Таких блоков сделать столько, во сколько форм надо занести значения
Set objExcel = ThisWorkbook.Sheets("TestEUR")
objExcel.Cells( 1 ,  10 ).Value = dt
objExcel.Cells( 9 ,  3 ).Value = oms_eur_acc
objExcel.Cells( 10 ,  5 ).Value = oms_eur_res
objExcel.Cells( 10 ,  11 ).Value = oms_eur_nres
objExcel.Cells( 12 ,  5 ).Value = oms_eur_es

Set objExcel = ThisWorkbook.Sheets("TestUSD")
objExcel.Cells( 1 ,  10 ).Value = dt
objExcel.Cells( 9 ,  3 ).Value = oms_usd_acc
objExcel.Cells( 10 ,  5 ).Value = oms_usd_res
objExcel.Cells( 10 ,  11 ).Value = oms_usd_nres
objExcel.Cells( 12 ,  5 ).Value = oms_usd_es


'# очищаем память, необязательно, но желательно
Set objFSO = Nothing
Set objDialog = Nothing
Set objTextFile = Nothing
strNextLine = Empty
Set objExcel = Nothing

End Sub
...
Рейтинг: 0 / 0
автоматизация
    #36396537
m (MaximuS)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hugo121Делал на днях подарок бухгалтершам к Новому Году - оказывается, они каждый день
вдвоём тратят кучу времени и нервов, выбирая из распечатанного на несколькихх листах текстовика,
который выдаёт система, данные (много чисел, выборочно из кучи ненужной информации,
подчёркивая нужное по линеечке), которые плюсуют на калькуляторе в много сумм, которые затем заносят
в несколько форм в Экселе и распечатывают
Мне кажется такого рода повторяющиеся монотонные задачи существуют в 95% компаниях и так вручную эти задачи обрабатывают 95% персонала. Потому что времени на "подумать" не хватает, надо же выйти 20 раз за день покурить и рассказать что вчера на ужин кушали :). У меню вот тоже была бы куча монотонной работы, которая занимала бы дни!, а так я заинтересовался автоматизацией 2 года назад и есть результат, на ту же работу теперь тратятся часы. Я вот в своей компании подумаваю как бы организовать курсы эффективной работы с Экселем. Может и Вам стоит своиx бухгалтерш обучить немного. И руководство заметит, если еще не заметило :).
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / автоматизация
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]