Доброго времени суток.
Признаюсь, до работы в компании Fast Reports, никогда не писал на Visual Basic. Не могу сказать, что в настоящее время познал этот язык, однако, по работе часто приходится отвечать на вопросы программистов, использующих VB6 для разработки программ и использующих Fast Report для генерации отчётов.
Ниже показан небольшой пример кода, который эмулирует Master/Detail функциональность при помощи пользовательского датасета (TfrxUserDataSet).
Код
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
Dim frx As TfrxReport Dim master_index As Integer Dim detail_index As Integer Dim mas(1 To 3, 1 To 20) As Integer Dim WithEvents master_dataset As TfrxUserDataSet Dim WithEvents detail_dataset As TfrxUserDataSet Private Sub Command1_Click() frx.ShowReport End Sub Rem ***** MASTER DATASET ***** Private Sub master_dataset_OnCheckEOF(IsEOF As Boolean) If master_index = 20 Then IsEOF = True Else IsEOF = False End If End Sub Private Sub master_dataset_OnFirst() master_index = 1 End Sub Private Sub master_dataset_OnGetValue(ByVal VarName As Variant, Value As Variant) If VarName = "Field1" Then Value = mas(1, master_index) ElseIf VarName = "Field2" Then Value = mas(2, master_index) ElseIf VarName = "Field3" Then Value = mas(3, master_index) End If End Sub Private Sub master_dataset_OnNext() master_index = master_index + 1 End Sub Private Sub master_dataset_OnPrior() master_index = master_index - 1 End Sub Rem ***** DEATIL DATASET ***** Private Sub detail_dataset_OnCheckEOF(IsEOF As Boolean) If detail_index = 20 Then IsEOF = True Else IsEOF = False End If End Sub Private Sub detail_dataset_OnFirst() detail_index = 1 End Sub Private Sub detail_dataset_OnGetValue(ByVal VarName As Variant, Value As Variant) If VarName = "Detail_1" Then Value = "Master is " + Str(master_index) ElseIf VarName = "Detail_2" Then Value = mas(2, detail_index) ElseIf VarName = "Detail_3" Then Value = mas(3, detail_index) End If End Sub Private Sub detail_dataset_OnNext() detail_index = detail_index + 1 End Sub Private Sub detail_dataset_OnPrior() detail_index = detail_index - 1 End Sub Private Sub Design_Click() Dim designer As TfrxDesigner Set designer = CreateObject("FastReport.TfrxDesigner") Rem It would be better to keep commented the following line 'designer.Standalone = True frx.DesignReport Set designer = Nothing End Sub Private Sub Form_Load() Dim i As Integer Dim j As Integer Set frx = CreateObject("FastReport.TfrxReport") Set master_dataset = CreateObject("FastReport.TfrxUserDataSet") Set detail_dataset = CreateObject("FastReport.TfrxUserDataSet") frx.EngineOptions.SilentMode = simMessageBoxes Rem Fill data with random values Randomize Timer For i = 1 To 3 Step 1 For j = 1 To 20 Step 1 mas(i, j) = Round(Rnd(1000) * 1000) Next j Next i master_dataset.Name = "MyDataSet" master_dataset.Fields = "Field1" + Chr(13) + Chr(10) + "Field2" + Chr(13) + Chr(10) + "Field3" detail_dataset.Name = "DetailDataSet" detail_dataset.Fields = "Detail_1" + Chr(13) + Chr(10) + "Detail_2" + Chr(13) + Chr(10) + "Detail_3" frx.LoadReportFromFile ("UserDataSet.fr3") master_index = 1 detail_index = 1 frx.SelectDataset True, master_dataset frx.SelectDataset True, detail_dataset End Sub Private Sub Form_Unload(Cancel As Integer) frx.SelectDataset False, master_dataset frx.SelectDataset False, detail_dataset Set detail_dataset = Nothing Set master_dataset = Nothing Set frx = Nothing End Sub |
Основная "фишка" примера находится в подпрограмме (кажется, это так называется в Бейсике?) detail_dataset_OnGetValue. При возвращении значения следует учитывать индекс текущей записи родительского бэнда.
Другой важный момент, на который стоит обратить внимание, это анализ EOF в подпрограмме detail_dataset_OnGetValue. Для простоты этот пример подразумевает, что любая мастер запись содержит 20 детализированных записей. Разумеется, в реальной программе анализ количества детализированных записей должен также основываться на проверке индекса текущей записи родительского бэнда.
К сожалению, этот пример не будет корректно работать в среде VB6. Генерация событий, используемых в этом примере, возможна лишь при создании исполняемого (EXE) файла.