Страницы: 1
RSS
Добавление данных в шаблон или добавление шаблона к данным? как?
 
Добрый день. подскажите можно ли организовать работу с шаблоном в такой ситуации.  
Допустим мы имеем некую книгу эксель, в которой первый лист это данные, а остальные листы это рассчеты ссылающиеся на эти данные.  
Причем на первом листе это данные полученные путем импорта файла ТХТ.  
если удалось реализовать макрос который импортирует этот текстовик, можно ли остальные листы как-то шаблоном добавлять к полученному файлу, или наоборот данные полученные путем импорта файла, как то копировать или добавлять в шаблон, тут не знаю что реальнее?  
Спасибо.
 
Что реальнее - сложно сказать.  
Реально и то и другое, и в обоих случаях достаточно 1-2 строк кода.  
 
Всё зависит от того, что и зачем вы делаете.  
Одного не понимаю - нафига плодить листы?  
Почему в книге не оставить 2 листа - шаблон с кнопкой инпорта из TXT, и лист расчётов  
Зачем данные переносить из TXT в Excel на отдельные листы, если макрос может выполнить импорт из TXT в любой момент?
 
По большому счёту, можно тхт вообще не импортировать в том смысле, как это понимает ТС.  
Можно макросом взять из него нужные данные и использовать их в рассчётах.  
Т.е. имеем файл с шаблоном для вывода результатов и макрос (может быть в лругом файле).  
Макрос открывает текст, выбирает нужные данные, производит расчёты, выгружает результаты на лист.  
Или выгружает на лист только нужные данные из тхт, которые далее используются в формулах листа.
 
к сожалению из-за политики в области инф. безопасности наверно не смогу выгрузить файл, а создать дома подобный  с ложными цифрами не просто -(  
почему подгружаю -  потомучто моих знаний хватает только на это) записываю макрос корректирую для моих нужд, получаю чистые данные.  
исходный текстовик содержит не только цифры но и заголовки столбиков и строк, а также спец символы типа │ ┐ ┴  и подобное. их-то я и использую при импорте как разделители, тем самым отчищая файл. как импортировать его иначе я не знаю, видимо вы имеете в виду, что каждое значение подгружается определенным образом, ненужное отсеивается, но как такое можно реализовать?  
2EducatedFool листы там в принципе не плодятся, допустим лист 1 это листа с данными, лист 2 это таблица, каждая ячейка ссылается на определенные ячейки на листе один, тем самым подсчитывая какие-либо показатели (суммируя например столбик 2, 3, 4 и строки 5 и 6), то же самое на остальных листах (3 и 4), только другие таблички. есть более изящное решение по импорту, а не через подгрузку с разделителями? я пробовал макросами с этого форума, но данные перекашиваются. видимо из за спец символов.  
2HUGO а как не импортировать и брать макросом? если я допустим в экселе могу ссылаться на ячейку А3, то на что я в коде буду ссылаться для тхт файла??? на позицию?? то есть 5 строка 5 по счету значение? но это тогда будет один символ, а цифры меняются как понять где одно начинается, где кончается, на какие позиции ссылаться?
 
Читаем весь текст в массив, разбивая его по концам строк.  
Например:  
 
   Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(MyPath & "input.txt", 1)  
   strContents = objFile.ReadAll: objFile.Close: Set objFile = Nothing  
   arrLineList= Split(strContents, vbCrLf)  
   strContents = Empty  
 
Далее перебираем циклом массив arrlines, каждую строку разбиваем на "ячейки" по разделителям или позиции в строке, пробелы убрать с помощью Trim().  
Т.е. получаем что-то вроде листа, но в памяти.  
Практически все задачи по анализу тхт можно таким способом выполнить.  
 
"5 строка 5 по счету значение" - это arrlines(4), а 5-ое значение можно получить например так:  
 
Trim(Mid(arrLineList(4), 17, 4)) 'ENT  
 
А вот  кусок рабочего кода по наполнению массива данными тхт:  
 
for y = 0 to UBound(arrLineList)  
Dt(y+1,1) = Trim(Mid(arrLineList(y), 1, 6)) 'NAME  
Dt(y+1,2) = Trim(Mid(arrLineList(y), 7, 3)) 'ID  
Dt(y+1,3) = Trim(Mid(arrLineList(y), 10, 3)) 'ST  
Dt(y+1,4) = Trim(Mid(arrLineList(y), 13, 4)) 'CS  
Dt(y+1,5) = Trim(Mid(arrLineList(y), 17, 4)) 'ENT  
next  
 
Но конечно нужно видеть Ваш тхт и корректировать код по месту - наверняка какие-то строки можно при анализе пропускать, какие-то разбивать иначе.  
Всё это можно организовать дополнительными проверками на наличие "индикаторов" в строке - например, если три первых знака строки цифры, то так поступаем, а если там "---" , то иначе, а если пусто - то вообще строку пропускаем.
 
arrlines=arrLineList  
это я частично пост правил, не до конца доправил...
 
ну по поводу примера, сделал, но очень урезанный, строк больше в неск раз.
 
Данные взять можно.  
Немного дело кодировка портит, но это поправимо.  
Лучше бы конечно оригинальный файл видеть, а то там с кодировками каша.  
 
Но вообще задача в целом непонятна.  
Можно ведь сделать, как Вы и писали, файл-шаблон с формулами и одним чистым листом.  
Этот тхт вполне можно импотировать стандартным способом на лист, затем сохранить файл с другим именем.  
Записать процесс в макрос, затем на чистом шаблоне его выполнить.  
Например так, ничего не изменяя в полученном коде:  
 
Sub Macro1()  
'  
' Macro1 Macro  
' Macro recorded 05.12.2011 by Hugo  
'  
 
'  
   With ActiveSheet.QueryTables.Add(Connection:= _  
       "TEXT;C:\tmp\Ырфи\Ырфи_post_285004.TXT", Destination:=Range("A1"))  
       .Name = "Ырфи_post_285004"  
       .FieldNames = True  
       .RowNumbers = False  
       .FillAdjacentFormulas = False  
       .PreserveFormatting = True  
       .RefreshOnFileOpen = False  
       .RefreshStyle = xlInsertDeleteCells  
       .SavePassword = False  
       .SaveData = True  
       .AdjustColumnWidth = True  
       .RefreshPeriod = 0  
       .TextFilePromptOnRefresh = False  
       .TextFilePlatform = 866  
       .TextFileStartRow = 1  
       .TextFileParseType = xlFixedWidth  
       .TextFileTextQualifier = xlTextQualifierDoubleQuote  
       .TextFileConsecutiveDelimiter = False  
       .TextFileTabDelimiter = True  
       .TextFileSemicolonDelimiter = False  
       .TextFileCommaDelimiter = False  
       .TextFileSpaceDelimiter = False  
       .TextFileColumnDataTypes = Array(9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, _  
       2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9, 2, 9)  
       .TextFileFixedColumnWidths = Array(1, 27, 1, 13, 1, 14, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, _  
       1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14)  
       .TextFileTrailingMinusNumbers = True  
       .Refresh BackgroundQuery:=False  
   End With  
End Sub  
 
 
Что в итоге нужно получить?
 
так попробовал код, вопрос возник в плане, что остается символ ----- в виде длинной полосы, вот, и непонятно почему он слово "Таблица" разорвал и потерял букву А? может можно ли эту строку всю "таблица *** *** *** *" пихнуть в первый столбик?  
а так все вроде как надо, ну а нужно на основе этого получить рассчеты, я и думал что как -то добавить этот лист в шаблон. например на шаблоне все таблицы заполнены формулами ссылающимися на "Лист1" но листа 1 нету, вот мы берем полученные лист втот щаблон и добавляем. соответсвенно формулы все просчитают. и готово.    
либо может проще делать как-то иначе, например лист 1 там уже присутствует пустым, а в него данные копируются.  
либо же может взять просто вариант EducatedFool, и просто по кнопке в файл добавлять, но у меня обычно новый файл создается, как сделать  что бы он в существующий добавил данные без создания новых книг и листов.
 
Полосу таким подходом не выкинуть.  
Строку в первый столбик тоже не впихнуть.  
Буква А пропала потому, что я вертикальные полосы выкидывал, вот заодно и А пропала.  
Можно А с полосами оставить, тогда будут лишние столбцы с полосами, ну или смотря как Вы данные по столбцам разобъёте.  
Если импортировать тест чтением в массив и обработкой массива - это всё можно почистить, выгрузить на лист только полезные данные, или вообще только итоговый результат обработки.  
"например лист 1 там уже присутствует пустым, а в него данные копируются" - так если Вы код пробовали, то так ведь и было - книга с пустым листом (сохранить её перед выполнением кода), а на других листах могут быть Ваши формулы.  
После выполнения кода сохраните книгу под другим именем или закройте без сохранения, когда высчитанные данные заберёте.
 
2Hugo  
все понял, спасибо!!!!!!  
только вот по массиву, если например через массив, это то что вы давали двумя постами выше?
 
Да, но там конечно работы много, чтоб всё красиво получить - строки нужно тоже и выкидывать, и объединять...
 
а можете посоветовать, что стоит почитать по VBA  и про массивы полезное на будущее?)(для "не очень программиста") а то я чувствую с текстовиками мне еще много работать)
 
Я ничего не посоветую, т.к. сам ничего кроме форумов не читал. Я тоже не программист.  
"Изучить вопрос" лень заставила - ну не возможно это всё вручную делать....  
Так, в самом начале просматривал http://www.firststeps.ru раздел VBA by Step - но там чтение и запись текстовых файлов другим способом освещается. Хотя и так тоже можно делать, и делают.  
И про массивы я там тоже ничего не нашёл (только что искал...)  
 
Я думаю так - найдите похожий не особо сложный пример на форуме, и постарайтесь код разобрать, понять что зачем делается. Если будут вопросы - задавайте тут, ответим.  
Потом аналогично пробуйте сделать свою задачу.  
Но именно этот текстовый файл не самый простой, если Вам нужно и из первого столбца инфу из трёх строк в одну собрать. И кодировка ещё дело усложняет.  
Хотя сделать можно, если постараться.  
А если нужно только цифры из определённых строк взять - то легко.
 
Спасибо попробую таким образом разобраться.  
нет мне нужно только получить данные ничего не складывая между собой. все расчеты уже отдельно потом.
 
Смотрю ещё раз на данные -  
если Вы собираетесь тянуть ВПР()ом данные по первому столбцу например по "1.2. ееееее ее ее е " и Вам совершенно не важно, что там в этой логической ячейке ещё есть "    (1.2.1+1.2.2+1.2.3)" (эти данные не нужны), то задача обработки файла простая:  
1. читаем в массив как выше в коде, или читаем файл построчно (если сотни мегабайт)  
2. перебираем построчно и заносим в словарь Trim(Mid(arrLineList(y), 2, 27)) (если оно непустое), а в связанный массив все остальные нужные ячейки строки (строки с "----------------" можно из обработки выкинуть, а можно и оставить, на работоспособность не влияет)  
3. теперь в любое время по "1.2. ееееее ее ее е" можно получить из словаря/массива данные этой строки.  
 
Если нужно выгрузить на лист все значимые собранные данные, то мусор из массива отсеивается легко - берём перебором только те строки, где в первом столбе цифры.
 
это пока сложно воспринять) вообщем попробовал следующим образом сделать. тяну так    
Sub Import()  
Dim strPath As String  
Dim fd As FileDialog  
Dim vrtSelectedItem As Variant  
   Set fd = Application.FileDialog(msoFileDialogFilePicker)  
   With fd  
       .AllowMultiSelect = False  
       .Filters.Clear  
       .Filters.Add "Text Files", "*.txt"  
       If .Show = -1 Then  
           strPath = vrtSelectedItem  
    With ActiveSheet.QueryTables.Add(Connection:= _  
       "TEXT;strPath" _  
       , Destination:=Range("$A$1"))  
       .Name = "strPath"  
       .FieldNames = True  
       .RowNumbers = False  
       .FillAdjacentFormulas = False  
       .PreserveFormatting = True  
       .RefreshOnFileOpen = False  
       .RefreshStyle = xlInsertDeleteCells  
       .SavePassword = False  
       .SaveData = True  
       .AdjustColumnWidth = True  
       .RefreshPeriod = 0  
       .TextFilePromptOnRefresh = False  
       .TextFilePlatform = 850  
       .TextFileStartRow = 2  
       .TextFileParseType = xlDelimited  
       .TextFileTextQualifier = xlTextQualifierDoubleQuote  
       .TextFileConsecutiveDelimiter = False  
       .TextFileTabDelimiter = False  
       .TextFileSemicolonDelimiter = False  
       .TextFileCommaDelimiter = False  
       .TextFileSpaceDelimiter = False  
       .TextFileOtherDelimiter = "¦"  
       .TextFileColumnDataTypes = Array(1)  
       .TextFileTrailingMinusNumbers = True  
       .Refresh BackgroundQuery:=False  
   End With  
   Union(Range( _  
       "81:81,84:84,86:86,89:89,91:91,94:94,96:96,98:98,100:100,103:103,105:105,107:107,109:109,112:112,114:114,116:116,118:118,121:121,124:124,126:126,128:128,132:132,134:134,136:136,138:138,140:140,143:143,145:145,148:148,152:152,154:154,156:156" _  
       ), Range( _  
       "159:159,163:163,167:167,169:169,4:4,7:7,9:9,11:11,15:15,18:18,20:20,23:23,25:25,27:27,29:29,32:32,34:34,36:36,39:39,41:41,44:44,47:47,49:49,51:51,53:53,55:55,57:57,59:59,61:61,63:63,65:65,68:68" _  
       ), Range("72:72,75:75,77:77,79:79")).Select  
   Range("A169").Activate  
   Selection.Delete Shift:=xlUp  
   Range("A102:A103").Select  
   Selection.Cut  
   Range("B102").Select  
   Range("A1:A3").Select  
   Selection.Cut  
   Columns("A:A").Select  
   Selection.Delete Shift:=xlToLeft  
         End If  
   End With  
   Set fd = Nothing  
End Sub  
 
но что-то не работает... ругается в частности на Refresh BackgroundQuery:=False
 
мне кажется код не работает потмоучто функция импорта текста как-то завязана на имя файла поэтому когда я пытаюсь вставить диалог выбора файла вба редактор ругается...  
как в таком случае можно реализовать что бы имя файла не нужно было менять каждый раз в вба редакторе? можно реализовать например что бы брался файл с именем таким же как имя книги , или еще как-то? но что бы это не противоречило функции импорта?
 
With ActiveSheet.QueryTables.Add(Connection:= _  
"TEXT;" & strPath _
 
2HUGO спасибо !!!
Страницы: 1
Читают тему
Наверх