Глава 5. Основы разработки программного обеспечения
При создании объекта Recordset могут быть определены динамические или статические его типы (см. таблицу 5.7).
Таблица 5.7. Типы объекта Recordset в библиотеках ADO и DAO
|
ADO |
|
|
DAO |
|
|
|
|
Тип |
Краткое описание |
Тип |
Краткое описание |
|
Dynamic |
Позволяет видеть добав- |
Dynamic- |
Результат |
|
выполнения |
cursor |
ление, изменение, удале- |
type |
запроса для |
одной |
|
или |
|
ние записей, выполняе- |
|
нескольких таблиц |
базы |
(adOpen- |
мые другими пользовате- |
|
данных, в котором можно |
Dynamic) |
лями. Метод <Record- |
|
добавлять, изменять |
или |
|
set>.Update |
позволяет |
|
удалять |
записи. Метод |
|
обновить записи в табли- |
|
<Recordset>.Update поз- |
|
це базы данных. |
|
|
воляет обновить запись в |
|
|
|
|
таблице базы данных, ес- |
|
|
|
|
ли до редактирования за- |
|
|
|
|
писи был выполнен метод |
|
|
|
|
Recordset>.Edit. |
|
|
Keyset |
Позволяет видеть измене- |
Dynaset- |
Результат выполнения |
|
cursor |
ние записей, не позволяет |
type |
запроса, который может |
|
видеть добавленные запи- |
|
обновлять записи в таб- |
(adOpen- |
си, не позволяет редакти- |
|
лицах базы данных. |
|
|
Keyset) |
ровать удаленные записи, |
|
Можно добавлять, изме- |
|
|
|
при выполнении этих |
|
нять, или удалять записи |
|
операций другими поль- |
|
одной таблицы или не- |
|
зователями. |
|
|
скольких таблиц. |
|
|
Static |
Статическая копию ряда |
Snapshot- |
Статическая копия ряда |
cursor |
записей, которую можно |
type |
записей, которую можно |
|
использовать, чтобы |
|
использовать, чтобы |
|
|
(adOpen- |
найти данные или генери- |
|
найти данные или гене- |
Static) |
ровать отчеты. |
|
|
рировать отчеты |
|
|
Forward- |
Позволяет перемещаться |
Forward- |
Идентичен типу Snapshot |
only cur- |
только вперед в объекте |
only-type |
за исключением того, что |
sor |
Recordset. Добавления, |
|
курсор |
не |
создается. |
|
изменения или удаления |
|
Можно только выполнить |
(adOpen- |
записей другими пользо- |
|
перемещение |
вперед |
че- |
Forward- |
вателями не видимы. Ис- |
|
рез записи. |
Можно |
ис- |
Only) |
|
пользуется, когда необхо- |
|
пользовать, когда необ- |
|
|
|
димо однократное про- |
|
ходимо |
сделать |
един- |
|
хождение по записям объ- |
|
ственный |
проход |
через |
|
екта Recordset. |
|
|
записи. |
|
|
|
|
|
|
|
|
|
|
|
|
Table-type |
Позволяет добавлять, из- |
|
|
|
|
менять или удалять запи- |
|
|
|
|
си в одной из таблиц базы |
|
|
|
|
данных. |
|
|
|
|
|
|
|
|
|
|
|
|
441 |
Глава 5. Основы разработки программного обеспечения
Для создания объекта Recordset в процедурах базы данных Access используется следующий синтаксис:
recordset.Open <источник>, <соединение>, <тип курсора>, <тип блокировки>, <опции>
где источник – SQL-запрос или объект Command ;
соединение – информация о связи с данными (ConnectionString) ;
тип курсора – см. таблицу 5.7;
тип блокировки – оптимистическая (adLockOptimistic, запись блокирует-
ся только в момент сохранения), пессимистическая (adLockPessimistic, запись блокируется в начале ее редактирования) и пр.;
опции – используется, если источник – Command.
Некоторые основы работы с объектами библиотеки Access и использования возможностей библиотек ADO и DAO рассмотрены далее на примере расчета сдельного наряда (данные, приведенные в примере, взяты из системы «Зарплата» функционировавшей на одном из предприятий, разработчиком которой в системе FoxPro был автор данного учебника).
Схема фрагмента базы данных, связанная с данной задачей, показана на рисунке 5.58.
Рисунок 5.58. Схема базы данных сдельного наряда
Глава 5. Основы разработки программного обеспечения
Внешний вид экранной формы для работы со сдельными нарядами показан на рисунке 5.59.
Рисунок 5.59. Сдельный наряд в Microsoft Office Access
На данной форме присутствуют данные четырех таблиц базы ZRPL:
SP_NAR – список нарядов и общие данные наряда;
RAB_NAR – данные работников в наряде;
ZATR – суммы затрат по различным ШПЗ в наряде;
ITR – справочник работников.
С объектами формы связано достаточно много процедур. Для главной формы заданы процедуры обработки события Load (выполняется при загрузке формы в память) и Current (выполняется при перемещении по записям и при обновлении формы), а также в разделе General-Declaration описана глобальная переменная NN (см. рисунок 5.60).
В процедуре Form_Load формы Список нарядов одна строка:
DoCmd.GoToRecord,, acLast – перейти на последнюю запись
данных формы.
В процедуре Form_Current две строки:
443
Глава 5. Основы разработки программного обеспечения
Form_refr – выполнение процедуры для задания нередактируемых полей год и месяц, если они ранее были определены для наряда (редактирование возможно только для новой записи).
Find_TK – выполнение процедуры для определения тарифных коэффициентов текущего месяца; процедура Find_TK описана в том же окне кода формы Список нарядов.
Рисунок 5.60. Процедуры событий Load и Current формы Список нарядов базы данных Zrpl в окне редактора Visual Basic
Текст этих двух процедур:
Private Sub Form_refr() |
|
If Not IsNull(Me.GOD) Then |
' Me.GOD – поле с именем GOD |
Me.GOD.Enabled = False |
' текущей формы |
Else |
' к значению поля текущей |
Me.GOD.Enabled = True |
' формы можно обращаться |
End If |
' и без Me, а только по имени |
If Not IsNull(Me.MES) Then |
|
Me.ПолеСоСписком21.Enabled = False
Else
Me.ПолеСоСписком21.Enabled = True
End If
End Sub
Глава 5. Основы разработки программного обеспечения
Sub Find_TK()
'поиск тарифных коэффициентов для текущего месяца и года 'в таблице mes_god, содержащей эти значения
Dim rs_mg As New ADODB.Recordset Dim s_sql As String
's_sql – строка запроса на языке SQL
s_sql = "SELECT mes_god.* FROM mes_god " & _
"WHERE mes_god.GOD = " & Me.GOD & _
"and mes_god.MESIJC = " & Me.MES & ""
'текст SQL-запроса - источник данных Recordset 'Set rs_rn = CurrentDb.OpenRecordset(s_sql) 'для DAO rs_mg.Open s_sql, CurrentProject.Connection, _
adOpenStatic, adLockReadOnly
'открыть RecordSet - 2-й вариант - ADO
'для текущего проекта Access,динамический курсор,
'оптимистическая блокировка записей
With rs_mg |
' далее к методам и свойствам объекта rs_mg |
|
' можно обращаться, начиная с точки |
ts(1) = !R1 |
|
ts(2) = !R2 |
|
ts(3) = !R3 |
|
ts(4) = !R4 |
|
ts(5) = !R5 |
|
ts(6) = !R6 |
|
.Close |
|
End With |
|
End Sub |
|
Если при исполнении данной программы или последующих появля-
ется сообщение об ошибке компиляции "User-defined type not defined", зна- чит Вы не подключили библиотеку ADO (см. рисунок 5.55).
В окне кода формы Список нарядов присутствуют также и другие процедуры для различных объектов данной формы.
Для поля GOD процедура события AfterUpdate, которая выполняется при изменении значения этого поля:
Private Sub GOD_AfterUpdate()
Find_TK
End Sub
Для поля со списком MES процедура события AfterUpdate, которая выполняется при изменении значения этого поля:
Private Sub ПолеСоСписком21_AfterUpdate()
Find_TK
End Sub
445
Глава 5. Основы разработки программного обеспечения
Для кнопки Расчет процедура события Click, которая выполняется при нажатии на эту кнопку:
Private Sub Расчет_Click()
' *** расчет сдельной оплаты по наряду |
*** |
'Dim rs_rn As DAO.Recordset |
' 1-й |
вариант - DAO |
Dim rs_rn As New ADODB.Recordset ' 2-й |
вариант - ADO |
Dim NN As Double |
|
|
Dim s_sql As String |
|
|
NN = Me.NOMER ' NOMER – имя поля на форме |
' Me - текущий объект - |
форма Список нарядов |
s_sql = "SELECT rab_nar.*, rab_nar.NOMER " & _
"FROM rab_nar WHERE rab_nar.NOMER = " & NN & "" 'Set rs_rn = CurrentDb.OpenRecordset(s_sql)
' открыть RecordSet 1-й вариант - DAO rs_rn.Open s_sql, CurrentProject.Connection, _
&adOpenDynamic, adLockOptimistic
'открыть RecordSet - 2-й вариант - ADO
'для текущего проекта Access,динамический курсор,
'оптимистическая блокировка записей
s_t_vr_ktu = 0 |
'сумма тариф*вредность*КТУ |
With rs_rn |
' |
далее к методам и свойствам объекта rs_rn |
|
' можно обращаться, начиная с точки |
'.Edit 'нужно только для 1-го варианта - DAO |
.MoveFirst |
|
|
Do Until.EOF |
|
|
'далее после знака ! – обращение к полям rs_rn
If Not IsNull(!TARIF) Then
If IsNull(!VREDNOST) Then VRDN = 1 _
Else VRDN = !VREDNOST s_t_vr_ktu = s_t_vr_ktu + !TARIF * VRDN * !KTU Debug.Print !TARIF, s_t_vr_ktu
End If
.MoveNext Loop
s_dopl = Me.SUM_nar - _
[Form_Работники в наряде подч_форма].[Всего_тариф]
.MoveFirst |
|
|
Do Until.EOF |
|
|
'.Edit |
' - нужно только для 1-го варианта - DAO |
If IsNull(!VREDNOST) Then VRDN = |
1 _ |
|
Else VRDN = |
!VREDNOST |
!SUMMA = !TARIF + s_dopl / s_t_vr_ktu * _ |
|
!TARIF |
* VRDN * !KTU |
'Сумма сдельной оплаты = сумме оплата по тарифу +
'доплата, распределяемая пропорционально тарифной
'оплате с учетом коэффицментов вредности и КТУ
Глава 5. Основы разработки программного обеспечения
!SUMMA = Round(!SUMMA, 2) Debug.Print !SUMMA
.Update
.MoveNext Loop
.Close End With
End Sub
Для формы Затраты по наряду определена одна процедура для события AfterUpdate, которая оперативно обновляет значения сумм затрат по наряду в этом окне и в родительском (Parent) окне (Список нарядов):
Private Sub SUM_ZATR_AfterUpdate()
Me.Refresh
Me.Parent.Refresh
[Form_Список нарядов].[SUM_nar] = SUM_Z
End Sub
Для формы Работники в наряде подч_форма определены следующие процедуры:
Для поля OTR_CHAS процедура события AfterUpdate, которая выполняется при изменении значения этого поля:
Private Sub OTR_CHAS_AfterUpdate()
Calc_tarif
End Sub
Для поля OTR_DN процедура события AfterUpdate, которая выполняется при изменении значения этого поля:
Private Sub OTR_DN_AfterUpdate() OTR_CHAS = 8 * OTR_DN Calc_tarif
End Sub
процедура расчета суммы оплаты по тарифу:
Private Sub Calc_tarif()
If Not IsNull(Me.RAZRD) And _ (IsNull(Me.TARIF_K) Or Me.TARIF_K = 0) _
Then Me.TARIF_K = ts(Me.RAZRD) Me.TARIF_K = Round(Me.TARIF_K, 2)
End If
Me.TARIF = OTR_CHAS * TARIF_K
Me.Refresh End Sub
В окне Module1 в разделе General-Declaration содержится описание общего для нескольких окно массива:
447
Глава 5. Основы разработки программного обеспечения
Public ts(6) As Single
В этом окне могут присутствовать также различные служебные программы для работы с информацией базы данных.
Еще один пример одновременной работы с Access и Word – программа чтения данных из таблицы файла *.doc или *.docx с перенесением их в таблицу базы данных. В рассмотренном примере используется таблица Список базы данных Контингент (см. раздел учебника 3.3.4.3 Созда-
ние базы данных в Microsoft Office Access 2007) и таблица Word (файл d:\asg\Список студ.doc), по содержанию соответствующая некоторым полям таблицы Список (см. таблицу 5.8).
Таблица 5.8. Таблица файла d:\asg\Список студ.doc
|
№ за- |
|
Фамилия, имя, отче- |
|
Дата |
|
Фа- |
|
Специ- |
Курс |
|
Груп- |
|
четки |
|
ство |
|
поступления |
|
культет |
|
альность |
|
па |
|
|
|
|
|
|
|
555274 |
|
Логинов Василий Ива- |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
нович |
|
|
|
|
|
|
|
|
|
|
|
|
555275 |
|
Минин Максим Викто- |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
рович |
|
|
|
|
|
|
|
|
|
|
|
|
555276 |
|
Лыжников Евгений |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
Анатольевич |
|
|
|
|
|
|
|
|
|
|
|
|
555278 |
|
Ляпин Игорь Василье- |
25.07.2006 |
5 |
0701 |
3 |
131 |
|
вич |
|
|
|
|
|
|
|
|
|
|
|
|
555280 |
|
Медников Николай Ви- |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
тальевич |
|
|
|
|
|
|
|
|
|
|
|
|
555281 |
|
Мальчук Елена Алек- |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
сандровна |
|
|
|
|
|
|
|
|
|
|
|
|
555282 |
|
Мальцев Вячеслав Вик- |
25.07.2006 |
5 |
2603 |
3 |
007 |
|
торович |
|
|
|
|
|
|
|
|
|
|
|
|
555283 |
|
Митин Владимир Се- |
25.07.2006 |
5 |
0701 |
3 |
131 |
|
менович |
|
|
|
|
|
|
|
|
|
|
|
|
555284 |
|
Маслов Владимир Ми- |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
хайлович |
|
|
|
|
|
|
|
|
|
|
|
|
555285 |
|
Мельников Виктор |
25.07.2006 |
5 |
2603 |
3 |
009 |
|
Петрович |
|
|
|
|
|
|
|
|
|
|
|
|
555288 |
|
Кулин Сергей Юрьевич |
25.07.2006 |
5 |
0701 |
3 |
131 |
Программу следует написать, как процедуру обработки события Нажатие кнопки (Click) для новой кнопки с именем Данные из Word, которую можно разместить на новой или существующей форме.
Текст процедуры может быть, например, следующий:
Private Sub Данные_из_Word_Click()
On Error Resume Next
Dim s_sql As String
'в таблице 1 документа Word
' строка для записи неудачных операций.Update ' строка для записи удачных операций.Update
Глава 5. Основы разработки программного обеспечения
Dim rs As New ADODB.Recordset
s_sql = "SELECT Список.* FROM Список"
'текст SQL-запроса - источник данных Recordset rs.Open s_sql, CurrentProject.Connection, _
adOpenDynamic, adLockOptimistic
'создаем динамический курсор для таблицы Список
'с оптимистической блокировкой записей
Set objWord = CreateObject("Word.Application")
'создаем объект типа Word.Application
objWord.Visible = True 'до завершения отладки использовать Visible
Set objDoc = objWord.Documents.Open("d:\Список студ.doc")
'открываем файл для объекта objWord
n = objDoc.Tables(1).Rows.Count 'определяем количество строк
no_dat = "" yes_dat = "" For i = 2 To n
s = objDoc.Tables(1).Rows(i)
'i-я строка таблицы 1 документа fld = Split(s, Chr(13) + Chr(7))
' i-тую строку таблицы разбиваем на поля для массива fld With rs ' далее к методам и свойствам объекта rs
' можно обращаться, начиная с точки
|
|
|
|
.AddNew |
'добавить строку в курсор |
|
.Fields("NZ") = fld(0) |
' присвоение полю NZ |
' набора записей rs значения элемента массива fld(0) |
.Fields("FIO") = fld(1) |
|
' ФИО |
.Fields("DATA_P") = CDate(fld(2)) |
' дата |
.Fields("N_FCLT") = Eval(fld(3)) |
' № фак. |
.Fields("N_SPECT") = fld(4) |
|
' Код спец |
.Fields("KURS") = Eval(fld(5)) |
' Курс |
.Fields("N_GRUP") = fld(6) |
|
' № группы |
.Update |
' пытаемся сохранить курсор в таблице базы |
If Err.Number <> 0 Then 'если сохранить не удается |
no_dat = no_dat & fld(0) & " |
" & fld(1) & vbLf |
Else
yes_dat = yes_dat & fld(0) & " " & fld(1) & vbLf
End If
End With
449
Глава 5. Основы разработки программного обеспечения
Next rs.Close objDoc.Close objWord.Quit
MsgBox "Всего в таблице Word " & n & " строк " & vbLf & _
"Добавлены в таблицу Список записи с Таб.№ :" & vbLf & _ yes_dat & _
"Не добавлены из-за нарушений целостности базы::" _
& vbLf & no_dat,, "Результаты переноса данных"
End Sub
Результаты выполнения программы будут показаны в окне MsgBox (см. рисунок 5.61).
Рисунок 5.61. Сообщение после выполнения процедуры добавления записей в таблицу Access их таблицы Word