|
|
|
| Еще раз доброго времени суток!
вот что имею, написанный мною через одно место но работающий код
1. GetSQL
2. DoCmd.OutputTo acQuery, "фильтрпоизделию", acFormatXLS, "фильтр.xls", False, "", 0
3. Set xlapp = CreateObject("Excel.Application")
4. Set xlbook = xlapp.Workbooks.Open("фильтр.xls")
5. Set xlsheet = xlbook.ActiveSheet
6. xlsheet.Name = "фильтр"
7. xlbook.SaveAs (ExportFile), xlNormal
8. xlbook.Close
9. Set xlbook = xlapp.Workbooks.Open(ExportFile)
10. Set xlsheet = xlbook.Worksheets("фильтр")
11. xlsheet.Activate
|
бился три дня, но знаю можно написать легче и проще, долго открывает... немного опишу по пунктам:
1. Выполняю функцию сбора данных (по принцыпу луковской кукурузы)
2. Импортирую в файл Excel - по другому не умею =)
3. Приложение Excel
4. Открываю импортируемый файл
5. Как я понял выбираю активный лист =)
6. переименовываю лист
7. Сохраняю все это дело (вот тут проблема, т.к. пункт 2 сохраняет почему то только для чтения, а моя основная задача это редактирование листа, об этом во втором вопросе =)))
8. Закрываю книгу
9. Открываю книгу =)
10. выбираю лист
11. делаю его активным
.... дальше начинаю редактировать....
собственно вопрос: как упростить все это? Заранее прошу не материться, для меня почему то экспорт в эксель оказался ахилесовой пятой.... =(( | |
|
| |
|
|
|
| продолжение кода
with xlsheet
.Range("A1:Q109").Select
.Application.Selection.Sort Key1:=Range("B1"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
end with
|
пытаюсб применить сортировку... первый раз все нормально делает, второй раз запускаю жалуется на метод "range" | |
|
| |
|
|
|
| я делаю вот так...
Dim jkl As String
jkl = CurrentProject.Path 'считываем путь проекта
Dim dfr As Object
Dim dfg As Object
Set dfg = CreateObject("Excel.Sheet")
Set dfr = dfg.Parent
dfr.Workbooks.Add jkl & "\ШаблонОтчета.xls" 'открываем шаблон
dfr.Visible = False 'True если показать окно Excel, но лучше потом когда всю инфу выгрузишь
dfr.ActiveWindow.WindowState = xlMaximized
'далее dfr. и чего хочешь сделать dfr.cells(1,1)="Всякая ерунда" запишет в ячейку А1 фразу всякая ерунда
попробывал выгрузку в ексель получился вот такой код
DoCmd.OutputTo acTable, "Таблица1", "MicrosoftExcelBiff8(*.xls)", "c:\просто.xls", False, "", 0
обратите внимание как Акс написал тип выводимых данных и имя файла (а точнее путь)
проверил файл - галка "только чтение" сброшена
далее - зачем п. 7,8,9,10,11
типа - ага что бы непотерялись данные будем после каждого действия сохраняться закрываться потом открываться получать доступ к нужному листу немного редактировать и так по кругу
еще - проверьте подключение библиотеки Microsoft Excel в Tools-References(это в редакторе VBA Акса) - если библиотека не подключена то некоторое специфичные для Екселя команды выполняться не будут | |
|
| |
|
|
|
| 1. Библиотеку подключил (она и была включена)
2. пункты 7,8,9,10,11 убрал - и правда они не к чему
3. А вот с сортировкой не получается... первый раз сортирует, а второй ошибку выдает, мне кажется не правильно я пишу все это, может кто знает? | |
|
| |
|
|
|
| ну то что убрали - это лишнее
т.е. нужно сделать всё - а потом сохранять,
отключаться и т.д. | |
|
| |
|
|
|
| ну а с сортировкой что? кто нибудь сортировал данные в Excel из VBA? я уже все варианты испробывал, ругается.... | |
|
| |
|
|
|
| Сортируйте изначальный запрос (перед выгрузкой)
или попробуйте вот так
with xlsheet
.Range("A1:Q109").Select
.Range("Q109").Activate
.Selection.Sort Key1:=Range("B1"), Order1:=xlAscending, Header:= _
xlGuess, OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
DataOption1:=xlSortNormal
end with | |
|
| |
|
|
|
|
Сортируйте изначальный запрос (перед выгрузкой)
|
а это идея -) только как программно енто сделать?
С сортировкой более менее разобрался, ошибка была тут
Key1:=Range("B1") он понимает Key1:= .Range("B1") - точку поставить нужно и грузит молодец =)
|
Спасибо snipe - твои советы навели меня на правельные мысли =)
Еще вопросик по теме...
В выгруженном уже файле Excel нужно произвести объединение... в конкретном столбце.
Я написал так (это предварительный макрос еще в Excel):
Sub объединение()
For i = 2 To 100
If Range(Cells(2, 2), Cells(2, 2)) = Range(Cells(i + 1, 2), Cells(i + 1, 2)) Then
Range(Cells(i, 2), Cells(i + 1, 2)).Select
Application.DisplayAlerts = False
Selection.Merge
Else
b = i + 1
For c = i + 1 To 100
If Range(Cells(b, 2), Cells(b, 2)) = Range(Cells(c + 1, 2), Cells(c + 1, 2)) Then
Range(Cells(b, 2), Cells(c + 1, 2)).Select
Application.DisplayAlerts = False
Selection.Merge
Else
d = c + 1
For f = c + 1 To 100
If Range(Cells(d, 2), Cells(d, 2)) = Range(Cells(f + 1, 2), Cells(f + 1, 2)) Then
Range(Cells(d, 2), Cells(f + 1, 2)).Select
Application.DisplayAlerts = False
Selection.Merge
Else
Exit For
End If
Next f
Exit For
End If
Next c
Exit For
End If
Next i
End Sub
|
По русски:
Усли ячейка А равна ячейке Б то мы их объединяем, цикл, если ячейка А равна ячейки В то мы их объединяем, ну и так далее... Если не равна (то есть все одинаковые значения объеденены), то переходим к следующей ячейки и выполняем подобный цикл только с другими значениями.... и так 7 раз....
Блин, это у меня в столбце могут быть только 7 различных значений... А если 107? я же хзамучаюсь писать =) может у кого дельный совет найдется? | |
|
| |
|
|
|
| DoCmd.OutputTo создает редактируемый файл, правда - в старом (5,0/95) формате. Почему у вас не так - непонятно. Какая версия Акса? Прилинкованный лист можете редактировать?
Что мешает отсортировать записи в запросе? | |
|
| |
|
|
|
|
Что мешает отсортировать записи в запросе?
|
мешает незнание как это сделать автоматически... так бы с удовольствием, может кинете примерчик? =)
DoCmd.OutputTo создает редактируемый файл, правда - в старом (5,0/95) формате
|
вот почему я пересохранял файл - вспомнил =) чтобы от формата этого избавиться - раздражал он меня =) | |
|
| |
|
|
|
| Если DoCmd.OutputTo только потому, что "по другому не умею =)", а объектную модель Excel-я вы используете, то есть смысл заготовить полностью отформатированный шаблон и вставлять данные методом CopyFromRecordset или методами объекта QueryTable.
Вставляемый Recordset можно отсортировать как угодно. | |
|
| |
|
|
|
| я в этой кухне никак вообще... может примерчик скинешь с рекордсетом и сортировкой в нем, ну и соответственно в эксель все это....
Я правда не знаю возможности рекордсета, но у меня динамический запрос, т.е. количество столбцов может меняться... Как то с шаблоном даже не знаю как быть...
Но в любом случае, если не трудно, скиньте примерчик, я разберусь, ну или ссылки какие нибудь, просто по множеству ссылок понять что написано можно только имея хотя бы базу знаний про рекордсет... | |
|
| |
|
|
|
|
| ооо =)) ты гений =))) а я то голову ломал =))) спасибо огромное =) вот еще добавил:
If .Range(.Cells(i, 3), .Cells(i, 3)) > 0 Then
на проверку пустых строк, чтобы их не объединяло =) | |
|
| |
|
|
|
| if nz(.Cells(i, 3) ,0)> 0 Then | |
|
| |
|
|
|
|
if nz(.Cells(i, 3) ,0)> 0 Then
|
а на
else
goto qwerty
....
next i
next j
qwerty:
Иначе если предел i стоит скажем 60000 - то очень долго обрабатывает (иногда и просто виснет), у меня таких циклов 4 штуки (на каждый столбец отдельно) | |
|
| |
|
|
|
| А зачем этот огород?
при чем тут 60000?
следите за мыслью
1. Dim переменная as Long
2. Динамически меняем строку SQL(на нужную) в сохраненном ранее запросе (можно не делать если все запросы сохранены)
3. Обновляем (DoCmd.Requery)
4. Экспортируем запрос в Ексель
5. переменная=количество строк в запросе
6. Получаем доступ к Екселю
7. Подцепляемся к нужному файлу
8. И вот цикл For i=2 to переменная+1 (+1 потому-что в первой строке у вас заголовки столбцов)
ну и т.д | |
|
| |
|
|
|
| хм... вариант =) тогда вопросик по реализации, как присвоить переменной количество строк в выполненном запросе?
я так понял как то так
dim asd as long
asd = nz(dcount("[Счетчик]","[Запрос1]",0)
|
И еще один вопросик, посоветоваться так сказать
В таблице сейчас всего 350 строк 10 столбцов, из них 4 столбца обязательно попадают в ексель и одинаковые значения объединяются. Принцып объединения таков, проверяется равенство ячейки с следующей ячейкой и если "верно" то они объединяютя. Тогда получется что ексель выполняет 350*4 = 1400 объединений... Сейчас формирование такого отчета занимает примерно 45 секунд на моей машине, а если строк будет скажем 5000, а их будет столько скажем через месяца 2... тогда отчет по всей таблице будет довольно таки долго формироваться....
Я тут подумал, а что если сперва искать одинаковые ячейки, их выделять и все сразу объединять? тогда количество объединений будет меньше, соответственно формирование отчета будет быстрее.... Вот только как это реализовать, да и возможно ли это? | |
|
| |
|
|
|
| про количество строк поняли правильно
а вот в том коде который я вам присылал вы не разобрались совсем
а там принцип такой
берется ячейка из строки i и сверяется с ячейкой из строки i+j если совпадают то пытаемся вычислить диапазон который надо выделить а конец диапазона будет в предыдущей строке от ячейки которая не равна ячейке в строке i теперь когда диапазон известен можно и объединить
но брать ячейку i+1 нет смысла значит следующая ячейка с которой будем сравнивать будет i+j
таким образом вы все равно пробегаете по всем строкам (ну в вашем примере 350*4=1400) однако количество объединений будет гораздо меньше | |
|
| |
|
|
|
| буду разбираться, спасибо... ) | |
|
| |
|
14 Кб. |
|
| Вот - (было не много времени) - накидал примерчик | |
|
| |
|
|
|
| просто и понятно =) спасибо =) теперь не так много времени занимает выгрузка =) | |
|
| |
|
|
|
| Как Вы славно разрулили....
Если уж Вам не влом - может тут поможете человеку?
http://hiprog.com/forum/read.php?id_forum=4&id_theme=7013&page=1 | |
|
| |