Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: немного по Excel...
 
 автор: АлаяЗаря   (26.03.2010 в 22:52)   личное сообщение
 
 

Еще раз доброго времени суток!

вот что имею, написанный мною через одно место но работающий код


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. делаю его активным
.... дальше начинаю редактировать....

собственно вопрос: как упростить все это? Заранее прошу не материться, для меня почему то экспорт в эксель оказался ахилесовой пятой.... =((

  Ответить  
 
 автор: АлаяЗаря   (26.03.2010 в 23:08)   личное сообщение
 
 

продолжение кода


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"

  Ответить  
 
 автор: snipe   (27.03.2010 в 04:02)   личное сообщение
 
 

я делаю вот так...

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 Акса) - если библиотека не подключена то некоторое специфичные для Екселя команды выполняться не будут

  Ответить  
 
 автор: АлаяЗаря   (27.03.2010 в 10:50)   личное сообщение
 
 

1. Библиотеку подключил (она и была включена)
2. пункты 7,8,9,10,11 убрал - и правда они не к чему
3. А вот с сортировкой не получается... первый раз сортирует, а второй ошибку выдает, мне кажется не правильно я пишу все это, может кто знает?

  Ответить  
 
 автор: snipe   (27.03.2010 в 13:41)   личное сообщение
 
 

ну то что убрали - это лишнее
т.е. нужно сделать всё - а потом сохранять,
отключаться и т.д.

  Ответить  
 
 автор: АлаяЗаря   (28.03.2010 в 21:41)   личное сообщение
 
 

ну а с сортировкой что? кто нибудь сортировал данные в Excel из VBA? я уже все варианты испробывал, ругается....

  Ответить  
 
 автор: snipe   (29.03.2010 в 01:56)   личное сообщение
 
 

Сортируйте изначальный запрос (перед выгрузкой)

или попробуйте вот так

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

  Ответить  
 
 автор: АлаяЗаря   (29.03.2010 в 13:19)   личное сообщение
 
 


Сортируйте изначальный запрос (перед выгрузкой)


а это идея -) только как программно енто сделать?

С сортировкой более менее разобрался, ошибка была тут

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? я же хзамучаюсь писать =) может у кого дельный совет найдется?

  Ответить  
 
 автор: Анатолий (Киев)   (29.03.2010 в 13:16)   личное сообщение
 
 

DoCmd.OutputTo создает редактируемый файл, правда - в старом (5,0/95) формате. Почему у вас не так - непонятно. Какая версия Акса? Прилинкованный лист можете редактировать?

Что мешает отсортировать записи в запросе?

  Ответить  
 
 автор: АлаяЗаря   (29.03.2010 в 13:29)   личное сообщение
 
 


Что мешает отсортировать записи в запросе?



мешает незнание как это сделать автоматически... так бы с удовольствием, может кинете примерчик? =)


DoCmd.OutputTo создает редактируемый файл, правда - в старом (5,0/95) формате

вот почему я пересохранял файл - вспомнил =) чтобы от формата этого избавиться - раздражал он меня =)

  Ответить  
 
 автор: Анатолий (Киев)   (29.03.2010 в 15:08)   личное сообщение
 
 

Если DoCmd.OutputTo только потому, что "по другому не умею =)", а объектную модель Excel-я вы используете, то есть смысл заготовить полностью отформатированный шаблон и вставлять данные методом CopyFromRecordset или методами объекта QueryTable.
Вставляемый Recordset можно отсортировать как угодно.

  Ответить  
 
 автор: АлаяЗаря   (29.03.2010 в 15:22)   личное сообщение
 
 

я в этой кухне никак вообще... может примерчик скинешь с рекордсетом и сортировкой в нем, ну и соответственно в эксель все это....


Я правда не знаю возможности рекордсета, но у меня динамический запрос, т.е. количество столбцов может меняться... Как то с шаблоном даже не знаю как быть...

Но в любом случае, если не трудно, скиньте примерчик, я разберусь, ну или ссылки какие нибудь, просто по множеству ссылок понять что написано можно только имея хотя бы базу знаний про рекордсет...

  Ответить  
 
 автор: snipe   (30.03.2010 в 00:44)   личное сообщение
 
 

по поводу макроса в екселе

вы чего творите?

уж как то так
for i=2 to 100
for j=1 to 65535-i
if cells(i,2)=cells(i+j,2) then
else
if j>1 Then
range(cells(i,2),cells(i+j-1,2).select
Application.DisplayAlerts = False
selection.merge
i=i+j
exit for
else
exit for
end if
end if
next j
next i


по поводу вывода формата файла ексель вот эта надпись определяет версию вывода формата файла "MicrosoftExcelBiff5(*.xls)" - (95) "MicrosoftExcelBiff8(*.xls)" - (97-2003)

динамически изменять запрос
CurrentDb.QueryDefs("Запрос1").SQL = "SELECT Таблица1.Материал, Таблица1.Счетчик, Таблица1.Дата FROM Таблица1 ORDER BY Таблица1.Дата;"

как видите это всего лишь текстовая строка которую можно переписать (тут кстати грабли есть - при закрытии базы запрос сохранится в этом виде)

посчитать количество записей в запросе
nz(dcount("[Счетчик]","[Запрос1]",0) - это напримере вышеописанного запроса

а еще лучше - разберитесь с recordset

  Ответить  
 
 автор: АлаяЗаря   (30.03.2010 в 02:05)   личное сообщение
 
 

ооо =)) ты гений =))) а я то голову ломал =))) спасибо огромное =) вот еще добавил:

If .Range(.Cells(i, 3), .Cells(i, 3)) > 0 Then

на проверку пустых строк, чтобы их не объединяло =)

  Ответить  
 
 автор: snipe   (30.03.2010 в 02:12)   личное сообщение
 
 

if nz(.Cells(i, 3) ,0)> 0 Then

  Ответить  
 
 автор: АлаяЗаря   (30.03.2010 в 17:43)   личное сообщение
 
 


if nz(.Cells(i, 3) ,0)> 0 Then



а на
else
goto qwerty
....
next i
next j
qwerty:

Иначе если предел i стоит скажем 60000 - то очень долго обрабатывает (иногда и просто виснет), у меня таких циклов 4 штуки (на каждый столбец отдельно)

  Ответить  
 
 автор: snipe   (31.03.2010 в 06:38)   личное сообщение
 
 

А зачем этот огород?
при чем тут 60000?

следите за мыслью
1. Dim переменная as Long
2. Динамически меняем строку SQL(на нужную) в сохраненном ранее запросе (можно не делать если все запросы сохранены)
3. Обновляем (DoCmd.Requery)
4. Экспортируем запрос в Ексель
5. переменная=количество строк в запросе
6. Получаем доступ к Екселю
7. Подцепляемся к нужному файлу
8. И вот цикл For i=2 to переменная+1 (+1 потому-что в первой строке у вас заголовки столбцов)

ну и т.д

  Ответить  
 
 автор: АлаяЗаря   (31.03.2010 в 13:50)   личное сообщение
 
 

хм... вариант =) тогда вопросик по реализации, как присвоить переменной количество строк в выполненном запросе?

я так понял как то так


dim asd as long
asd = nz(dcount("[Счетчик]","[Запрос1]",0)



И еще один вопросик, посоветоваться так сказать

В таблице сейчас всего 350 строк 10 столбцов, из них 4 столбца обязательно попадают в ексель и одинаковые значения объединяются. Принцып объединения таков, проверяется равенство ячейки с следующей ячейкой и если "верно" то они объединяютя. Тогда получется что ексель выполняет 350*4 = 1400 объединений... Сейчас формирование такого отчета занимает примерно 45 секунд на моей машине, а если строк будет скажем 5000, а их будет столько скажем через месяца 2... тогда отчет по всей таблице будет довольно таки долго формироваться....

Я тут подумал, а что если сперва искать одинаковые ячейки, их выделять и все сразу объединять? тогда количество объединений будет меньше, соответственно формирование отчета будет быстрее.... Вот только как это реализовать, да и возможно ли это?

  Ответить  
 
 автор: snipe   (01.04.2010 в 05:06)   личное сообщение
 
 

про количество строк поняли правильно

а вот в том коде который я вам присылал вы не разобрались совсем
а там принцип такой
берется ячейка из строки i и сверяется с ячейкой из строки i+j если совпадают то пытаемся вычислить диапазон который надо выделить а конец диапазона будет в предыдущей строке от ячейки которая не равна ячейке в строке i теперь когда диапазон известен можно и объединить
но брать ячейку i+1 нет смысла значит следующая ячейка с которой будем сравнивать будет i+j
таким образом вы все равно пробегаете по всем строкам (ну в вашем примере 350*4=1400) однако количество объединений будет гораздо меньше

  Ответить  
 
 автор: АлаяЗаря   (01.04.2010 в 09:31)   личное сообщение
 
 

буду разбираться, спасибо... )

  Ответить  
 
 автор: snipe   (02.04.2010 в 05:45)   личное сообщение
14 Кб.
 
 

Вот - (было не много времени) - накидал примерчик

  Ответить  
 
 автор: АлаяЗаря   (02.04.2010 в 07:58)   личное сообщение
 
 

просто и понятно =) спасибо =) теперь не так много времени занимает выгрузка =)

  Ответить  
 
 автор: час   (02.04.2010 в 11:47)   личное сообщение
 
 

Как Вы славно разрулили....
Если уж Вам не влом - может тут поможете человеку?
http://hiprog.com/forum/read.php?id_forum=4&id_theme=7013&page=1

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList