Забыли пароль?

Master/Detail из пользовательского датасета в Visual Basic 6

Aleksey Mandrykin

Доброго времени суток.

Признаюсь, до работы в компании 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) файла.


назад