Страницы: 1 2 След.
RSS
Обработка большого объема данных в Excel
 
Доброй ночи!  
 
Пытаюсь настроить макрос для разбивки данных листа на файлы.  
Столбцов на листе 10, а вот строк ~ 100 000.  
 
Принцип разбивки на файлы: берется столбец, из уникальных значений к-ого формируется заголовок будущего файла и в этой формирующийся файл попадаются строки из исходного файла только с указанным значением в столбце.  
 
 
Пробовал разные вариант:  
1 вариант - пользуюсь давно, все ок, но при объеме > 50 000 строк макрос о-о-очень подвисает.  
2 вариант - пробовал загонять весь объем данных в массив и уже из массива получать нужные значения перебором. работает, но тоже медленно.  
3 вариант - пробовал через сводные. Работает быстрее предыдущих вариантов, но сам код получается очень сложным + всякие доп книги приходится создавать и тп.  
 
 
Подскажите, пож-та, как все-таки лучше в excele обрабатывать такой объем данных?  
Может есть другие алгоритмы для данной задачи, более производительные?  
 
 
Буду признателен за любые подсказки.  
 
==========================================  
 
 
Вариант 1:  
   Dim Wb As Workbook  
   Dim r As range, c As range, BasePath As String  
       Set r = range(TextBox2.Value & "2", range(TextBox2.Value & "1").End(xlDown))  
       BasePath = ActiveWorkbook.Path & "\Rezult\"  
       On Error Resume Next  
       With New Collection  
           For Each c In r  
               .Add 0, c  
               If Err Then  
                   Err.Clear  
               Else  
                   ActiveSheet.Copy  
                   range(r.Address).ColumnDifferences©.EntireRow.Delete  
                   Set Wb = ActiveWorkbook  
                   Wb.SaveAs BasePath & c & " - " & TextBox1.Value & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False  
                   Wb.Close False  
                   Err.Clear  
               End If  
           Next  
       End With  
         
==========================================  
 
 
Вариант 2 (кусок кода):  
 
Dim МассивДанных() As Variant  
Dim i As Long  
Dim j As Integer  
Dim x As Long  
МассивДанных = Sheets("Лист1").range("A1:Z150000").Value  
x = 0  
For i = 1 To 150000  
   If МассивДанных(i, 6) = "значение для поиска" Then  
       For j = 1 To 26  
           Sheets("Лист2").range(БукваСтолбца(j) & i - x).Value = МассивДанных(i, j)  
       Next j  
   Else  
       x = x + 1  
   End If  
Next i  
Erase МассивДанных  
 
==========================================  
 
 
Вариант 3:  
 
Dim tempWB As Workbook  
Dim tempДанные As Worksheet  
Dim tempСводная As Worksheet  
ActiveSheet.Copy: Set tempДанные = ActiveSheet  
tempДанные.Columns(27).Value = ActiveSheet.Columns(6).Value  
tempДанные.range("AA1").Value = "x-TEMP-x"  
Set tempWB = ActiveWorkbook: tempWB.Sheets.Add  
Set tempСводная = tempWB.ActiveSheet  
tempWB.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _  
   tempДанные.Name & "!R1C1:R5000C" & 26 + 1, Version:=xlPivotTableVersion12).CreatePivotTable _  
   TableDestination:=tempСводная.Name & "!R1C1", TableName:="СводнаяТаблица", DefaultVersion:=xlPivotTableVersion12  
With tempСводная.PivotTables("СводнаяТаблица").PivotFields("Продавец")  
   .Orientation = xlRowField  
   .Position = 1  
End With  
tempСводная.PivotTables("СводнаяТаблица").AddDataField tempСводная.PivotTables _  
   ("СводнаяТаблица").PivotFields("x-TEMP-x"), _  
   "Количество по полю x-TEMP-x", xlCount  
tempСводная.range("B2").ShowDetail = True
 
{quote}{login=Andrew}{date=13.07.2012 02:29}{thema=Обработка большого объема данных в Excel}{post}... Столбцов на листе 10, а вот строк ~ 100 000...  
... Принцип разбивки на файлы: берется столбец, из уникальных значений к-ого формируется заголовок будущего файла ...{/post}{/quote}Это ж сколько файлов будет из уникальных в СТА ТЫСЯЧАХ строк?
 
{quote}{login=Andrew}{date=13.07.2012 02:29}{thema=Обработка большого объема данных в Excel}{post}Подскажите, пож-та, как все-таки лучше в excele обрабатывать такой объем данных?  
Может есть другие алгоритмы для данной задачи, более производительные?  
{/post}{/quote}  
ADO или scripting.dictionary  
Вам в помощь, примеров на форуме масса
Спасибо
 
http://www.planetaexcel.ru/forum.php?thread_id=28031&page_forum=1&allnum_forum=56
Спасибо
 
Я бы использовал переработанный второй вариант (массивы)  
 
1) считываем массив  
МассивДанных = Sheets("Лист1").Range(Sheets("Лист1").[A1], Sheets("Лист1").Range("A" & Sheets("Лист1").Rows.Count).End(xlUp)).Value
 
2) получаем список уникальных значений из столбца:  
http://excelvba.ru/code/UniqueValuesFromArray  
 
3) в цикле, формируем отдельные массивы для каждого уникального элемента  
http://excelvba.ru/code/arrautofilter  
 
4) каждый из полученных массивов сохраняем в новую книгу Excel  
http://excelvba.ru/code/Array2worksheet  
или в CSV (c расширением XLS - тоже будет открываться нормально)  
http://excelvba.ru/code/Range2CSV
 
я бы еще объеденил пп 2-3 - т.е. на одном проходе и уникальные выявлять и массивы создавать...  
 
лучше сначала накапливать только одномерные массивы индексов - т.е. запоминать номер строки, подходящей по условию. можно прям в словаре, а можно создать свой тип данных и организовать массив массивов - так должно быть побыстрее.  
потом по этим индексам из большого массива переписывать во временный, поменьше и записывать в файл.
Живи и дай жить..
 
Можно и первый вариант подшаманить - только перебирать не ячейки, а массив из диапазона.  
Адрес нужной ячейки генерить кодом.  
Строки не удалять, а скрывать, видимые копировать в новый файл.  
Тоже должно быть приемлимо по скорости.
 
>> Михаил С.: Это ж сколько файлов будет из уникальных в СТА ТЫСЯЧАХ строк?  
 
Как правило, не больше 50-100 уникальных значений (т.е. на выходе 50-100 файлов). Файлов не много, но тут все дело в кол-ве строк, к-ые тормозят весь процесс.  
 
 
За подсказки всем БОЛЬШОЕ СПАСИБО. Буду пробывать.
 
Начал применять предложенные идеи/советы.  
Сперва тест ADO от Дмитрия.  
 
По любезно предоставленной Дмитрием ссылке нашел код, к-ый делает практически  все, что мне нужно. Разница лишь в том, что у Дмитрия код разбивает данные на листы, а у меня будет на книги. Но это мелочь, легко решаемо.  
 
Особенно меня поразила скорость работы макроса. Данные (10 столбцов:50000 строк) и с уникальными значениями = 30 шт обработка заняла 27 секунд !!! Это нечто :) Я предполагал прирост скорости, но на столько !!!! Супер.  
 
 
Главная проблема при интеграции этого кода - это кол-во строк. Т.к. у меня строк больше 64 000, то макрос не работает. Ругается на строку:  
rs.Open strSql, cn, adOpenStatic, adLockReadOnly  
 
Текст ошибки:  
run-time error '-2147217865 (80040e37)':  
Объект 'Общий$a2:j100000' не найден ядром базы данных Microsoft Jet.  
Проверьте существование объекта и правильность имени и пути.  
 
Если я правильно понял, все дело в версии Excel и в частности в строке подключения к базе:  
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 8.0;HDR=No"";"  
 
Если указываю Excel 12.0 (у меня Excel2007):  
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=No"";"  
 
то ругается уже на строку:  
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=No"";"  
 
текст ошибки:  
run-time error '-2147467259 (80004005)':  
Невозможно найти установленный ISAM.  
 
 
Подскажите, пожалуйста, что нужно допилить под работу с Excel 2007 и кол-вом строк > 64 000?  
 
 
======================================  
 
Код макроса прилагаю:  
 
Application.ScreenUpdating = 0  
 
Dim cn As ADODB.Connection, rs As ADODB.Recordset, lr As Long  
 
Set cn = New ADODB.Connection  
Set rs = New ADODB.Recordset  
Set rs2 = New ADODB.Recordset  
 
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 8.0;HDR=No"";"  
 
If Not cn.State = 1 Then Exit Sub  
 
With Worksheets("Общий")  
   lr = .Cells(.Rows.Count, 1).End(xlUp).Row  
End With  
 
strSql = "SELECT DISTINCT F5" & " FROM [Общий$a2:j" & lr & "] T "
rs.Open strSql, cn, adOpenStatic, adLockReadOnly  
rs2.Open "SELECT * FROM [Общий$a2:j" & lr & "] T ", cn, adOpenStatic, adLockReadOnly
 
For i = 0 To rs.RecordCount - 1  
   Worksheets.Add After:=Worksheets(Worksheets.Count)  
   With ActiveSheet  
       .Name = rs("F5").Value  
       rs2.Filter = "F5 = '" & rs("F5").Value & "' "  
       .[a1:j1] = Sheets("Общий").[a1:j1].Value
       .Cells(2, 1).CopyFromRecordset rs2  
       rs2.Filter = ""  
       rs.MoveNext  
   End With  
Next  
 
rs.Close: rs2.Close: cn.Close  
Set cn = Nothing: Set rs = Nothing: Set rs2 = Nothing  
 
Application.ScreenUpdating = -1
 
Как то делал подобную задачу, посмотрите, может подойдет. <BR>http://www.planetaexcel.ru/forum.php?thread_id=16778&page_forum=2&allnum_forum=24 <BR>сообщение от 13.06.2010, 17:33
 
[Andrew]>2 вариант - пробовал загонять весь объем данных в массив и уже из массива получать нужные значения перебором. работает, но тоже медленно.
из-за этой строки  
>Sheets("Лист2").range(БукваСтолбца(j) & i - x).Value = МассивДанных(i, j)
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
\пример, который можно ускорить
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Привет Саш, это у тебя такая новая фишка разбивать макрос на несколько функций? :)  
Чем отличается от просто_одного_макроса?  
 
В приведённом тобой примере, можно же сделать просто так:  
 
Sub UnVal()  
   Dim nCol As New Collection  
   Dim i&, FinalRow&  
   FinalRow = Cells(Rows.Count, 1).End(xlUp).Row  
 
   On Error Resume Next  
   For i = 1 To FinalRow  
       With Cells(i, 1)  
           nCol.Add .Value, CStr(.Value)  
       End With  
   Next  
 
   For i = 1 To nCol.Count  
       Cells(i, 3).Value = nCol.Item(i)  
   Next  
End Sub
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Пользуйтесь, можно существенно ускорить за счет другого алгоритма создания и добавления данных, не прибегая к методу ADD, но..... (можно написать в почту) не для форума...  
Sub test()  
Application.ScreenUpdating = 0  
Dim cn As ADODB.Connection, rs As ADODB.Recordset, lr As Long  
Set cn = New ADODB.Connection  
Set rs = New ADODB.Recordset  
Set rs2 = New ADODB.Recordset  
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 8.0;HDR=No"";"  
 
If Not cn.State = 1 Then Exit Sub  
 
With Worksheets("Общий")  
lr = .Cells(.Rows.Count, 1).End(xlUp).Row  
End With  
 
strSql = "SELECT DISTINCT F5" & " FROM [Общий$a2:j" & lr & "] T "
rs.Open strSql, cn, adOpenStatic, adLockReadOnly  
rs2.Open "SELECT * FROM [Общий$a2:j" & lr & "] T ", cn, adOpenStatic, adLockReadOnly
 
For i = 0 To rs.RecordCount - 1  
 
'Worksheets.Add After:=Worksheets(Worksheets.Count)  
'With ActiveSheet  
'.Name = rs("F5").Value  
rs2.Filter = "F5 = '" & rs("F5").Value & "' "  
'.[a1:j1] = Sheets("Общий").[a1:j1].Value
'.Cells(2, 1).CopyFromRecordset rs2  
AddBooks ThisWorkbook.Path & Application.PathSeparator & rs("F5").Value, rs2  
rs2.Filter = ""  
rs.MoveNext  
'End With  
Next  
rs.Close: rs2.Close: cn.Close  
Set cn = Nothing: Set rs = Nothing: Set rs2 = Nothing  
Application.ScreenUpdating = -1  
End Sub  
Sub AddBooks(NameBooks As String, ByVal rss As Object)  
   Workbooks.Add  
   With ActiveWorkbook  
   .Sheets(1).[a1].CopyFromRecordset rss
   .SaveAs Filename:= _  
       NameBooks, FileFormat:= _  
       xlOpenXMLWorkbook, CreateBackup:=False  
       .Close False  
   End With  
End Sub
Спасибо
 
Excel 12.0  
----------------  
забыл исправить
Спасибо
 
{quote}{login=LightZ}{date=13.07.2012 10:56}{thema=10110}{post}Привет Саш, это у тебя такая новая фишка разбивать макрос на несколько функций? :)  
Чем отличается от просто_одного_макроса?{/post}{/quote}  
Это, Богдан, называется "Процедурное программирование" [http://ru.wikipedia.org/wiki/%CF%F0%EE%F6%E5%E4%F3%F0%ED%EE%E5_%EF%F0%EE%E3%F0%E­0%EC%EC%E8%F0%EE%E2%E0%ED%E8%E5]  
 
"задачи разбиваются на шаги и решаются шаг за шагом. Используя процедурный язык, программист определяет языковые конструкции для выполнения последовательности алгоритмических шагов"  
 
Не стану разбирать твой код, но скажу - ошибок там хватает )  
 
P.S.: одну функций написанную мной в посте выше, сегодня использовал в реальной задаче. Просто и легко - копи-паст : )  
А ты каждый раз меняй/отслеживай логику одного макроса, следи за состоянием переменных, обработкой ошибок и т.д. и т.п.
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
немого по теме:  
 
Процедурное программирование   
http://programstudy.ru/procedure_programming  
 
Объектно-ориентированное программирование   
http://programstudy.ru/oop  
 
Обобщённое программирование   
http://programstudy.ru/generic_programming
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
 
Только сегодня удалось протестировать макросы.  
 
На текущий момент остановился на варианте, предложенным Игорем.  
После мизерной доработки получен желаемый результат: таблицу 10 на 100 000 (с 30 уник. значениями) макрос отрабатывает за 1 мин 15 сек.  
 
Игорь, большое вам спасибо за приведенный код!  
 
 
На этом я бы мог успокоиться, но никак не дает покоя код предложенный Дмитрием (а вдруг там еще быстрее) :))  
К сожалению, проверить код в работе не удалось, т.к. при запуске по-прежнему появляется ошибка run-time error '-2147217865 (80040e37):  
Объект 'Общий$a2:j100000' не найден ядром базы данных Microsoft Office Access.  
Проверьте существование объекта и правильность имени и пути.  
 
Может, у меня не установлены какие-нибудь referens?  
Список текущих (установленных) referens в вложении.  
 
 
 
Дмитрий, написал вам письмо по поводу "другого алгоритма создания и добавления данных". Очень любопытно...
 
Вообще-то тут 3 Игоря предложили варианты (хотя пример готового кода и впрямь только один...) :)  
1 мин 15 сек. - что-то долго для создания всего 30-ти файлов...
 
Игорь,заметь, если это тот вариант что писался 2 года назад, то весьма не плохо:) В том варианте есть то, что не знал на момент написания макроса. В каждой новой книге удаляю все листы перебором, конечно лишнее и время:( И потом самое длительное это сохранение книги и если 30 штук за 1.15 последовательно сохраняются на диск....
 
Попробуйте такой вариант своего первого варианта (за неимением Вашего примера я текстбоксы отключил):  
 
 
Sub tt()  
 
   Dim Wb As Workbook  
   Dim r As Range, ra, BasePath As String, i&, sh As Worksheet, copyrange As Range  
   Application.ScreenUpdating = False  
     
   '    Set r = Range(TextBox2.Value & "2", Range(TextBox2.Value & "1").End(xlDown))  
   Set r = [a1:a100]
   ra = r.Value  
 
   BasePath = ActiveWorkbook.Path & "\Rezult\"  
   Set sh = ActiveSheet  
   On Error Resume Next  
   With New Collection  
       For i = 1 To UBound(ra)  
           .Add 0, CStr(ra(i, 1))  
           If Err Then  
               Err.Clear  
           Else  
               r.EntireRow.Hidden = False  
               r.ColumnDifferences(sh.Range("A" & i)).EntireRow.Hidden = True  
               Set copyrange = r.SpecialCells(xlCellTypeVisible).EntireRow  
               Set Wb = Workbooks.Add(1)  
               copyrange.Copy Wb.Sheets(1).[a1]
               Wb.SaveAs BasePath & ra(i, 1) & " - " & "test" & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False  
               Wb.Close False  
               Err.Clear  
               Set Wb = Nothing  
               Set copyrange = Nothing  
           End If  
       Next  
   End With  
   r.EntireRow.Hidden = False  
   Application.ScreenUpdating = True  
End Sub
 
ну и про железо не забываем :)  
не помню, какой был макрос, приведенный на планете, но автор писал. что у него он работал сколько-то времени (опять-таки - не помню сколько именно)  
а на моем ноуте (Celeron Duo T3100 1.90GHz 3Gb RAM) он работал примерно в полтора раза дольше :(
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Чуть повыкидывал лишнее:  
 
 
Sub tt()  
 
   Dim Wb As Workbook  
   Dim r As Range, ra, BasePath As String, i&  
   Application.ScreenUpdating = False  
 
   '    Set r = Range(TextBox2.Value & "2", Range(TextBox2.Value & "1").End(xlDown))  
   Set r = [a1:a100]
   ra = r.Value  
   BasePath = ActiveWorkbook.Path & "\Rezult\"  
   
   On Error Resume Next  
   With New Collection  
       For i = 1 To UBound(ra)  
           .Add 0, CStr(ra(i, 1))  
           If Err Then  
               Err.Clear  
           Else  
               r.EntireRow.Hidden = False  
               r.ColumnDifferences(r(i)).EntireRow.Hidden = True  
               Set Wb = Workbooks.Add(1)  
               r.SpecialCells(xlCellTypeVisible).EntireRow.Copy Wb.Sheets(1).[a1]
               Wb.SaveAs BasePath & ra(i, 1) & " - " & "test" & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False  
               Wb.Close False  
               Err.Clear  
           End If  
       Next  
   End With  
   r.EntireRow.Hidden = False  
   Application.ScreenUpdating = True  
End Sub
 
{quote}{login=ikki}{date=15.07.2012 02:14}{thema=}{post}ну и про железо не забываем :)  
{/post}{/quote} Если я правильно понимаю - скорость макросов зависит от оперативной памяти и процессора?
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
В данном случае будет зависеть ещё и от диска - представьте супермедленный, да ещё с бэдами :)
 
Вообще-то тут 3 Игоря предложили варианты  
// Igor67  :)  
 
Hugo, спасибо за ваш вариант, но данный макрос работает дольше 5-и минут, потому уступает предыдущим в скорости.  
 
Вариант Igor67, немного доработанный мной, в конце поста.  
Странно, вчера макрос отработал за 1:15, сегодня уже 1:40 - 1:50.  
Скорее всего, оперативка какими-то др. процессами загружена. Впрочем, все равно очень даже приемлемо.  
 
Не подскажите, можно ли как-то упростить приложенный ниже макрос, оптимизировав какие-либо операции?  
 
============================  
 
   'отключаем обновление экрана  
   Application.ScreenUpdating = False  
   Application.DisplayAlerts = False  
   BasePath = ThisWorkbook.Path & "\Rezult\"  
   УдаляемСоздаемПапкуRezult  
   'вычисляем последнюю строку и последний столбец  
   iLastRow = Cells.SpecialCells(xlLastCell).Row  
   iLastCol = Cells.SpecialCells(xlLastCell).Column  
   'заносим в переменную букву столбца, по к-ому делаем выборку и формируем будующие заголовки файлов  
   startCol = TextBox2.Value  
   'получаем в переменную имя активного листа  
   startSh = ActiveSheet.Name  
   'заносим в массив все данные активного листа  
   arrAllData() = Range("A2:" & БукваСтолбца(iLastCol) & iLastRow)  
   'заносим в массив уникальные значенияColumn  
   arrName() = NoDups(Range(startCol & "2:" & startCol & iLastRow))  
   'присваеваем переменной диапазон с значениямиColumn  
   Set rngName = Range(startCol & "2:" & startCol & iLastRow)  
   'проверяем наличие записей  
   On Error GoTo 0: On Error Resume Next  
   lNr = UBound(arrName)  
   If Err.Number <> 0 Then  
       Application.DisplayAlerts = True  
       Application.ScreenUpdating = True  
       Статус = False  
       MsgBox "Выбранный столбец с данными не содержит значений.", vbCritical  
       Exit Sub  
   End If  
   'начинаем перебирать данные в массиве  
   For lNr = 1 To UBound(arrName())  
       Name = arrName(lNr)  
       'вычисляем количество повторов значенийColumn в диапазоне  
       colName = WorksheetFunction.CountIf(rngName, Name)  
       'переопределяем и очищаем массив с данными по конкретному значениюColumn  
       ReDim arrNameData(1 To colName, 1 To iLastCol)  
       Counter = 0  
       'начинаем считывание данных по значениюColumn из всего массива данных  
       For i = 1 To UBound(arrAllData())  
           'заносим данные по значениюColumn в массив по конкретному значениюColumn  
           If arrAllData(i, Columns(startCol).Column) = Name Then  
               Counter = Counter + 1  
               For j = 1 To iLastCol  
                   arrNameData(Counter, j) = arrAllData(i, j)  
               Next j  
           End If  
       Next i  
       'создаем новую книгу для вставки данных  
       Set tmpWb = Workbooks.Add(xlWBATWorksheet)  
       Set shNrName = tmpWb.Sheets(1)  
       'начинаем заносить данные  
       With shNrName  
           'наводим красоту вставляя отдельные значения и шапку таблицы  
           .Rows(1).Value = ThisWorkbook.Sheets(startSh).Rows(1).Value  
           .Rows(1).Font.Bold = True  
           .Cells.Font.Size = 9  
           .Cells.Font.Name = "Calibri"  
           .Cells(1, 1).Select  
           'если значений больше 1, вставляем нужное кол-во строк  
           If colName > 1 Then .Range("A2").Resize(colName - 1, iLastCol).Insert Shift:=xlDown, CopyOrigin:=xlFormatFromRightOrBelow  
           'присваеваем значения из массива по значениюColumn ячейкам (выгружаем массив)  
           .Range("A2:" & БукваСтолбца(iLastCol) & 1 + colName) = arrNameData()  
           'делаем автоподбор ширины столбцов  
           .Cells.EntireColumn.AutoFit  
           'присваеваем новое имя листу  
           shNrName.Name = "данные"  
       End With  
       'убираем все формулы на листе  
       shNrName.UsedRange.Cells.Value = shNrName.UsedRange.Cells.Value  
       'сохраняем созданную книгу  
       If TextBox1.Value = "" Then  
           tmpWb.SaveAs BasePath & Name & TextBox1.Value & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False  
       Else  
           tmpWb.SaveAs BasePath & Name & " - " & TextBox1.Value & ".xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False  
       End If  
       tmpWb.Close False  
   Next lNr  
       ThisWorkbook.Sheets(startSh).Select  
   Application.DisplayAlerts = True  
   Application.ScreenUpdating = True  
 
============================
 
Про 5 минут не верю.  
Ну разве что там ещё полно формул, которые пересчитываются при каждом действии.  
Тогда отключите пересчёт, или лучше всё делать на копии, очищенной от формул.  
 
Вообще это не дело - где пример файла с данными? Не надо тысячи, хватит 100 строк.  
Мой вариант на 100 строках с 10 уникальными работает 5 секунд. На 30 уникальных должно быть секунд 20-25.
 
{quote}{login=Andrew}{date=15.07.2012 03:43}{thema=}{post}Странно, вчера макрос отработал за 1:15, сегодня уже 1:40 - 1:50.{/post}{/quote}  
замечал такое за Excel'ем  
(честно говоря, точных причин не знаю)  
у меня, бывает, наблюдается разница в разы!  
поэтому, перед тем, как отдавать свои макросы другим людям, я провожу примерную оценку (в зависимости от объема данных, конечно) скорости их работы.  
и если при работе наблюдается значительная задержка, пользователю выдается сообщение с рекомендацией перезапустить Excel.  
срабатывает 100%.  
(конечно, когда сообщение бывает дочитано до конца и осмыслено:)
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Про 5 минут не верю. Ну разве что там ещё полно формул, которые пересчитываются при каждом действии.  
// Формул нет. Для теста брал просто текстовые данные (значения).  
 
Вообще это не дело - где пример файла с данными?  
// Исправляюсь. Пример в вложении (с немного доработанным макросом от Igor67)  
 
Мой вариант на 100 строках с 10 уникальными работает 5 секунд. На 30 уникальных должно быть секунд 20-25.  
// Тест я делал на 100 000 строк с 30 уникальными. Результат соответственно: ~2 min текущий макрос от Igor67, > 5 минут предложенный вами макрос.  
Если строк до 10 000, то любой из приложенный в данной теме макросов работает очень шустро. Разница практически незаметна. А вот если кол-во строк > 50 000, то отличия в скорости работы налицо.  
 
 
если при работе наблюдается значительная задержка, пользователю выдается сообщение с рекомендацией перезапустить Excel.  
// Перезапуск Excel как правило помогает. Но в данном случае почему не сработало. Возможно, вчера были немного другие данные, поэтому и скорость иная.
 
забудьте на больших объемах о функции  
Function NoDups(Rng As Range, Optional Mask = "*")
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


https://github.com/nervgh
Страницы: 1 2 След.
Читают тему
Loading...