Динамичесткий отчет

KiNDERok
Дата: 30.08.2005 19:06:15
Доброго времени суток!

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

Заранее благодарен.
Владимир Саныч
Дата: 30.08.2005 19:17:42
Столбцы создаются по максимуму и по мере необходимости прячутся и сдвигаются.
neal
Дата: 30.08.2005 21:51:10
Был пример в очень древней учебной базе (не Борей точно, как-то по другому называлась), которая шла еще с Access'ом 2.0 или 95:

Смысл в кратце -


в Header отчета ставяться поля Head1, Head2, Head3,...,HeadN - сколько помещаются на Вашем листе.
В Detail - под ними Col1, Col2, ...,ColN - поля или combobox'ы соответственно.
В Footer - Total1, Total2, ..., TotalN

Все элементы - свободные.RecordSource у отчета - пустой.

При открытии отчета открываете рекордсет Rs на основе Вашего (скорее всего перекрестного запроса)

В методе Header_Format пробегаете по запросу и берете первые N имен запроса

If (formatcount = 1) then
    For i = 1 to rs.field.Count
         if (i <= N) then
              me("Head" & i) = rs.field(i-1).Name
         endif
    next i
endif
В Detail_Format берете значения текущей строки рекордсета и переходите к следующей, а также в локальные переменные отчета суммируете значения для итога по столбу

В Footer_Format в поля Total1,...,TotalN записываете подсчитанные итоги.

В методе Close или UnLoad закрываете рекордсет.

Можете продумывать и многостраничные динамические отчеты в ширину.

-------------------------------------------------------
Зависть окружающих - это налог,который платит яркая индивидуальность.(с)Торо.
KiNDERok
Дата: 31.08.2005 12:55:03
Большое спасибо за ответ. Практически все работает(99%). Но осталась одна мелочь. Не могу реализовать "В Detail_Format берете значения текущей строки рекордсета и переходите к следующей".

Подскажите пожалуйста реализовать вывод на экран всех строк. Ибо выводит только значения последней строки запроса. Вот моя процедура.
Private Sub Область данных_Format(Cancel As Integer, FormatCount As Integer)
    Dim i, j As Long
    Call oNoPENrEPORT(Rs)
            i = 1
            Do While Not Rs.EOF
                For j = 1 To Rs.Fields.Count
                    If (j <= N) Then Me("Col" & j) = Rs.Fields(j - 1).Value
                Next j
                i = i + 1
                Rs.MoveNext
            Loop
            Rs.Close
End Sub
Orlic
Дата: 31.08.2005 13:45:45
Я сейчас эту проблему пытаюсь решить через экспорт в Exel... Так мне кажется удобнее для пользователя и изящнее: в лист Exelя переносятся только те данные, какие получаются в результирующем перекрестном запросе. А уж в Exel юзер может масштабировать, менять шрифты/цвета и прочее....
adv
Дата: 31.08.2005 13:59:00
KiNDERok
Ибо выводит только значения последней строки запроса.

Судя по вашему коду, он это и должен делать.


KiNDERok
реализовать вывод на экран всех строк

Назначить recordsource-ом отчёта ваш запрос, а recordsource-ом полей отчёта - поля запроса.
adv
Дата: 31.08.2005 14:12:34
adv
а recordsource-ом полей отчёта - поля запроса.

Виноват: ControlSource-ом полей отчёта - поля запроса.
neal
Дата: 01.09.2005 16:06:58
KiNDERok
Private Sub Область данных_Format(Cancel As Integer, FormatCount As Integer)
    Dim i, j As Long
    Call oNoPENrEPORT(Rs)
            i = 1
            Do While Not Rs.EOF
                For j = 1 To Rs.Fields.Count
                    If (j <= N) Then Me("Col" & j) = Rs.Fields(j - 1).Value
                Next j
                i = i + 1
                Rs.MoveNext
            Loop
            Rs.Close
End Sub

Нет, чуть-чуть не так.
call OnOpenReport(Rs) - это что такое? Оно открывает рекордсет?
Рекордсет отчета надо открывать в Header_Format(), а в области данных только брать значения из текущей записи рекордсета и переходить к следующей (ну можно еще посчитывать сумму для итога по столбцу или строке). В кратче код д.б. такой:

Private Sub Область данных_Format(Cancel As Integer, FormatCount As Integer)
    Dim i As Long
    If (Formatcount = 1) then
         For i = 1 to rs.field.Count
              if (i <= N) then
                   me("Col" & i) = rs.fields(i-1).Value
              end if
         next i
         Rs.MoveNext
     end if
End Sub

adv
Назначить recordsource-ом отчёта ваш запрос, а recordsource-ом полей отчёта - поля запроса.

Это я как раз бы не советовал, потому что отчет динамический и какие колонки в него попадут Вы не знаете, и если там будет поле ссылающееся на поле запроса, а этого поля в запросе не будет, то будет сообщение об ошибке.

Да и потом свободный отчет быстрее открывается в дизайнере.
-------------------------------------------------------
Зависть окружающих - это налог,который платит яркая индивидуальность.(с)Торо.
KiNDERok
Дата: 01.09.2005 16:54:47
Option Compare Database
Const N = 24
Private Sub Report_Open(Cancel As Integer)
    'Call oNoPENrEPORT(Rs)
End Sub

Sub oNoPENrEPORT(zz)
    Set db = Application.CurrentDb
    Set zz = db.OpenRecordset("5зпрДинамическиСтадия3")
End Sub

Private Sub ЗаголовокОтчета_Format(Cancel As Integer, FormatCount As Integer)
    Call oNoPENrEPORT(Rs)
    Dim i As Long
    If (FormatCount = 1) Then
        For i = 1 To Rs.Fields.Count
            If (i <= N) Then
                Me("Head" & i) = Rs.Fields(i - 1).Name
            End If
        Next i
    End If
    Rs.Close
End Sub

Private Sub ОбластьДанных_Format(Cancel As Integer, FormatCount As Integer)
    Call oNoPENrEPORT(Rs)
    Dim i, j As Long
            i = 1
            Do While Not Rs.EOF
                For j = 1 To Rs.Fields.Count
                    If (j <= N) Then
                       Me("Col" & j) = Rs.Fields(j - 1).Value
                    End If
                Next j
                i = i + 1
                Rs.MoveNext
            Loop
            Rs.Close
End Sub
Вот как выглядит весь мой код. В процедурах "ЗаголовокОтчета_Format", "ОбластьДанных_Format" я использую "Call oNoPENrEPORT(Rs)" что комп понял что такое RS (другой выход из этой ситуации я вижу так: где-то сверху объявить глобальную переменную RS, однако когда пишу Dim RS As RecordSet, то в строчке "For i = 1 To Rs.Fields.Count" пишет ошибку "Object required" я так понимаю, он не может распознать переменную RS). ОДНАКО и в этом случае он мне выводит значения последней строки (перекрестного) запроса.

Может ошибка где-то в настройках самого отчета?
KiNDERok
Дата: 01.09.2005 17:10:14
adv
adv
а recordsource-ом полей отчёта - поля запроса.

Виноват: ControlSource-ом полей отчёта - поля запроса.


Дело в том что число записей в запросе может превышать число столбцов в отчете, поэтому я не вижу выход в предложенных вами действиях