AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 07.06.2006, 18:25   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Gustav
1. Выводим в Excel данные из двух связанных таблиц: LedgerTrans и LedgerTable.
В эксперимент нужно обязательно добавить какое-нибудь вычисляемое поле.

Иначе самый быстрый вариант - передать в Excel запрос в инструмент Excel \ Data \ Import External Data \ New Database Query (спасибо Константину, который подсказал этот способ)

Проблемы начинаются, если в Excel'е нужно отобразить данные, которые вычисляются на X++ в коде Аксапты...

Кроме того, нужно определить что должен делать алгоритм, если получилось больше 65 тысяч строк...
__________________
полезное на axForum, github, vk, coub.
Старый 07.06.2006, 18:54   #2  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от mazzy
самый быстрый вариант - передать в Excel запрос в инструмент Excel \ Data \ Import External Data \ New Database Query
Разве этот вариант согласуется с этим пунктом условий?
Цитата:
Сообщение от Gustav
6. Рассматриваем только выгрузку средствами самой Аксапты. Доступ напрямую к таблицам БД средствами СУБД (MS SQL Server или Oracle), минуя Аксапту – не рассматриваем.
Старый 07.06.2006, 19:20   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от gl00mie
Разве этот вариант согласуется с этим пунктом условий?
ок. согласен, пропустил.
__________________
полезное на axForum, github, vk, coub.
Старый 07.06.2006, 20:20   #4  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Небольшой офф-топик: вывод на несколько листов Excel по 65 тыс. строк
"Раз уж заговорили об этом..."

Может, кому пригодится. Привожу фрагменты из рабочего кода на VBA, включающего в себя алгоритм перехода на следующий лист. Это НЕРАБОЧАЯ процедура, т.е. она взята из моего работающего приложения и из нее удалены отдельные фрагменты. Поэтому не пытайтесь запускать ее в Excel в том виде, в каком она здесь представлена. Однако, список переменных процедуры сохранен полностью. Не пытайтесь его понять полностью - там много ненужного, т.е. не имеющего отношения к переходу на след.лист. В принципе там всё несложно, другое дело, что часто такие вещи бывает делать лениво и они всё откладываются, откладываются...

Словом, если есть желание - воспользуйтесь. Если будут вопросы - с удовольствием отвечу.
Код:
'Код - Excel VBA

'ВНИМАНИЕ: запускать не надо, он все равно не запустится!
'А поизучать можно :)
'Может, кому-нибудь пригодится.

Option Explicit

Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset

Const MaxRowsPerSheet As Long = 65000 'максимальное количество, выводимое на один лист

Sub GenerateReport()
'эта процедура запускается, когда пользователь жмет на листе кнопку "Создать файл отчета"
'т.е. с нее всё и начинается
    Dim Id As Long
    Dim Rep_Id As Long
    Dim NewFile As Workbook
    Dim Res As Object
    Dim stmt As String
    Dim Title As String
    Dim flds() As Object
    Dim fldsNames() As String 'массив заголовков колонок
    Dim fldcount As Long
    Dim Colnum As Long
    Dim Rownum As Long 'строка Excel
    Dim HeaderRows As Long 'количество строк заголовков перед данными (2 штуки)
    
    Dim dtmProcStart As Date
    Dim lngProcSeconds As Long
    Dim strProcInfo As String
    
    Dim dtmQueryStart As Date
    Dim lngQuerySeconds As Long
    Dim strQueryInfo As String
    
    Dim dtmOutputStart As Date
    Dim lngOutputSeconds As Long
    Dim strOutputInfo As String
    
    Dim TitleOfPart As String
    
    Dim intOutputKind As Integer 'Вариант вывода: 1 - Традиционный, 2 - Быстрый
    Dim Recordnum As Long 'сквозной счетчик записей через все листы
    
    Dim func_needed As Integer
    Dim func_len As Long
    Dim func_name As String
    
    Dim rng As Range
    
    Dim actSheet As Worksheet
    Dim intSheetsCounter As Integer
        
        
    dtmOutputStart = Now
    Debug.Print "Начало вывода результатов: " & dtmOutputStart
    
    Set NewFile = Application.Workbooks.Add
    
    Application.ScreenUpdating = False
    
    intSheetsCounter = 1
    Set actSheet = NewFile.Worksheets(intSheetsCounter)
    actSheet.Select
    
    HeaderRows = 2
    
    Rownum = HeaderRows
    Recordnum = 0
    
    lngQuerySeconds = DateDiff("s", dtmQueryStart, Now)
    strQueryInfo = "Запрос был выполнен за " & CStr(lngQuerySeconds) & " сек (" & CStr(fldcount) & " полей). "
    Application.StatusBar = strQueryInfo & strProcInfo
    Debug.Print strProcInfo & strQueryInfo
    
    'собственно главный цикл вывода результатов
    '------------------------------------------------------------------------------------------------------------------
    Select Case intOutputKind
        Case 1
            '--- ORA
            Do While Not EmpDynaset.EOF
            
                Rownum = Rownum + 1
                Recordnum = Recordnum + 1
                
                For Colnum = 0 To fldcount - 1
                    actSheet.Cells(Rownum, Colnum + 1) = flds(Colnum).Value
                Next Colnum
                
                If (Recordnum Mod 100) = 0 Then
                    GoSub Every100rows
                End If
                
                EmpDynaset.DbMoveNext
            Loop
            
        Case 2
            '--- ADO
            Do While Not rst.EOF
            
                Recordnum = Recordnum + 100
                
                Set rng = actSheet.Cells(Rownum + 1, 1)
                rng.CopyFromRecordset Data:=rst, MaxRows:=100
                
                Rownum = Rownum + 100
                
                GoSub Every100rows
            Loop
            
    End Select
    
    '------------------------------------------------------------------------------------------------------------------
    
    Select Case intOutputKind
        Case 1
            '--- ORA
            Recordnum = EmpDynaset.RecordCount
            EmpDynaset.Close
            Set EmpDynaset = Nothing
        Case 2
            '--- ADO
            'rst.RecordCount - данный провайдер MSDAORA возвращает -1 для любого типа курсора, поэтому извращаемся на последнем листе
            Recordnum = (NewFile.Worksheets(intSheetsCounter).Range("A1").SpecialCells(xlCellTypeLastCell).Row - HeaderRows) _
                        + (intSheetsCounter - 1) * MaxRowsPerSheet
            rst.Close
            Set rst = Nothing
    End Select
    
    'форматирование последнего (или единственного) листа
    If intSheetsCounter > 1 Then
        TitleOfPart = "Ч." & CStr(intSheetsCounter) & ". " & Title
    Else
        TitleOfPart = Title
    End If
    
    Rownum = (Recordnum Mod MaxRowsPerSheet) + HeaderRows
    
    Call FormatResults(actSheet, TitleOfPart, fldcount, fldsNames, Rownum)
    
    strOutputInfo = "Вывод " & CStr(Recordnum) & " строк за " & CStr(lngOutputSeconds) & " сек. "
    Application.StatusBar = strOutputInfo & strQueryInfo & strProcInfo
    Debug.Print strProcInfo & strQueryInfo & strOutputInfo
    
'-- сделать возможность запуска того же запроса -- с дефолтно выключенной опцией "с теми же параметрами" -- а то упарился при тестировании
    

    Application.StatusBar = False
    Application.ScreenUpdating = True
    
    With NewFile.Worksheets(1)
        .Select
        .Range("A1").Select
    End With
    
    Exit Sub
    
Every100rows:
    'фрагмент вынесен в подпрограмму внутри процедуры - чтобы не создавать отдельную абстрактную процедуру
    'хоть это и ругаемый устаревший синтаксис, зато, блин, получилось весьма удобно :)))
    
    'каждые 100 строк обновляем StatusBar
    lngOutputSeconds = DateDiff("s", dtmOutputStart, Now)
    strOutputInfo = "Вывод " & CStr(Recordnum) & " строк за " & CStr(lngOutputSeconds) & " сек. "
    Application.StatusBar = strOutputInfo & strQueryInfo & strProcInfo
    
    If (Recordnum Mod MaxRowsPerSheet) = 0 Then
    'каждые 65000 строк переходим на след.лист
        'если сюда попали, то листов у нас точно больше одного
        
        'форматирование только что заполненного листа
        TitleOfPart = "Ч." & CStr(intSheetsCounter) & ". " & Title
        Call FormatResults(actSheet, TitleOfPart, fldcount, fldsNames, Rownum)
        
        If intSheetsCounter = 1 Then
            actSheet.Name = "Part_" & CStr(intSheetsCounter) 'переименовываем только что заполенный лист
        End If
        
        intSheetsCounter = intSheetsCounter + 1
        
        If intSheetsCounter > NewFile.Worksheets.Count Then
            'если листов не хватает, то добавляем в конец
            NewFile.Worksheets.Add.Move after:=NewFile.Worksheets(NewFile.Worksheets.Count)
        End If
        
        Set actSheet = NewFile.Worksheets(intSheetsCounter)
        actSheet.Name = "Part_" & CStr(intSheetsCounter) 'переименовываем вновь добавленный
        actSheet.Select 'это нужно в основном для версии 2 -- вывод через CopyFromRecordset (да и то не сильно обязательно)
        
        Rownum = HeaderRows 'сбрасываем счетчик строк Excel для следующего листа
    End If
    Return
    
End Sub
Старый 07.06.2006, 19:07   #5  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от mazzy
Excel \ Data \ Import External Data \ New Database Query
Можно считать, что этот способ отклоняется пунктом "6. Рассматриваем только выгрузку средствами самой Аксапты. Доступ напрямую к таблицам БД средствами СУБД (MS SQL Server или Oracle), минуя Аксапту – не рассматриваем."

Способы доступа к таблицам Аксапты внешними средствами безусловно интересны и, как правило, быстры. За исключением одного НО - они плюют на рогатки безопасности Аксапты, в частности, на RLS, и предъявляют все данные запроса без учета профиля пользователя, их запрашивающего. Недавно как раз этот момент обсуждался здесь: Альтернативные конструкторы отчетов в Axapta
Цитата:
Сообщение от mazzy
Кроме того, нужно определить что должен делать алгоритм, если получилось больше 65 тысяч строк...
Должен переходить на следующий лист Excel. Я уже выводил и 500 тысяч, и больше. Но в "Условиях конкурса" мы говорим о 50 тыс.
К тому же, тестируется скорость вывода. Скорость же "переворачивания" алгоритмом очередного эксельного шита пренебрежима мала

Раз уж заговорили об этом, процитирую себя, любимого, из письма к своим благодарным пользователям (речь о неком местном эксельном репортере):
Цитата:
Данная версия Репортера приспособлена для вывода больших
выборок (свыше 65 тыс.строк) на несколько листов рабочей
книги Excel. Каждый очередной переход на следующий лист
происходит автоматически по достижении очередных 65 тыс.
Нужное количество листов также автоматически добавляется.

Не стоит, однако, увлекаться слишком большими объемами
выводимых в отчет данных, т. к. могут возникнуть ограничения
со стороны оперативной памяти Вашего компьютера
и размера получающегося файла Excel, причем, даже если
Вам удастся сохранить такой огромный файл Excel
(много листов по 65 тыс.строк), в будущем Вы можете просто
его не открыть.
Цитата:
Сообщение от gl00mie
Разве этот вариант согласуется с этим пунктом условий?
и я про то же

Последний раз редактировалось Gustav; 07.06.2006 в 19:28.
Теги
benchmark, download, excel, faq, xml, законченный пример, производительность, экспорт/импорт

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Axapta программирует Excel на VBA Gustav DAX: База знаний и проекты 10 13.03.2006 11:42
Использование OWC.Spreadsheet для ускорения экспорта/импорта в/из Excel. storer DAX: Программирование 24 28.03.2005 19:10
Передача данных из 1С в Axapta 3.0 через COM Connector isbist DAX: Программирование 10 03.12.2004 10:58
Особенности экспорта данных в Excel Roman-sp DAX: Функционал 18 01.03.2004 12:07
Введение в Аксапту Роман Кошелев DAX: Прочие вопросы 0 18.12.2001 14:00

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 23:33.