Заполнение "отвязного" рекордсета данными из БД

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Заполнение "отвязного" рекордсета данными из БД

Сообщение sergey-911 » 10.04.2007 (Вт) 19:24

Доброе время суток уважаемые.
Разрабатываю клиент-серверные приложения. В качестве БД использую SQL сервер. Информацию в БД изменяю и заношу при помощи хранимых процедур.
Принцип этого механизма: сначала заполняю таблицу в клиентском приложении данными из БД; выполняю процедуру модификации (добавления, удаления, редактирования), передавая хранимой процедуре на сервере значения из клиентского приложения; для отображения корректной информации в таблице клиентского приложения, заново заполняю таблицу всеми записями из БД.
Получается, что для одной модификации на стороне сервера, делаю два обновления таблицы на стороне клиента, что занимает время и ресурсы.
Пытаюсь сделать безрезультатно такой механизм:
1) создать "отвязный" рекордсет (не подключенный к БД)
Код: Выделить всё

'Отвязанный рекордсет
Set rs = New ADODB.Recordset
rs.Fields.Append "№", adInteger
rs.Fields.Append "Название фильма", adVarChar, 100   
rs.Fields.Append "Актеры", adVarChar, 250
rs.Fields.Append "Жанр", adVarChar, 50
rs.Fields.Append "Примечание", adVarChar, 50
rs.Fields.Append "Отзыв", adVarChar, 50
rs.Fields.Append "FilmID", adInteger
'--------------
'???Заполнение отвязного рекордсета данными из БД???
'--------------
rs.Open

2) заполнить им таблицу в клиентском приложении;
3) после вызова процедуры добавления на сервере дополнить отвязный рекордсет новой информацией
Код: Выделить всё

frmADO.rs.AddNew
frmADO.rs!№ = Text1
frmADO.rs![Название фильма] = Text2
frmADO.rs!Актеры = Text3
frmADO.rs!Жанр = Text4
frmADO.rs!Примечание = Text5
frmADO.rs!Отзыв = Text6
frmADO.rs! FilmID = “значение идентификатора, возвратимое сервером”

4) соответственно, после вызова процедуры модификации на сервере изменить отвязный рекордсет новой информацией
Код: Выделить всё

frmADO.rs!№ = Text1
frmADO.rs![Название фильма] = Text2
frmADO.rs!Актеры = Text3
frmADO.rs!Жанр = Text4
frmADO.rs!Примечание = Text5
frmADO.rs!Отзыв = Text6

При таком механизме обновления данные из БД берутся только один раз, дальнейшие изменения будут сделаны путём хранимых процедур без постоянного обновления клиентского приложения из БД.
А теперь, собственно вопрос. Как в “отвязный” рекордсет поместить данные из БД, либо сделать рекордсет, подключённый к БД “отвязным”?
Прилагаю пример, толька в качестве БД в нём применяю Access/
С уважением, Сергей.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 10.04.2007 (Вт) 19:29

Суть и назначение отвязанных рекордсетов в данном случае мне неясна.
Но привязанный превращается в отвязанный после set .activeconnection=nothing.
Таки понимает ли автор, что он делает и зачем?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 10.04.2007 (Вт) 19:37

'frmADO (Форма с таблицей)
Код: Выделить всё

Option Explicit

Dim Soedinenie As String
Public rs As ADODB.Recordset

Private Sub Form_Load()
    'Параметры соединения
    Soedinenie = App.Path
    If Right$(Soedinenie, 1) <> "\" Then Soedinenie = Soedinenie & "\"
    Soedinenie = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
    Soedinenie & "ADO.mdb;Persist Security Info=False"
    'Набор записей из БД
    Set rs = New ADODB.Recordset
    Set rs = FIND("SELECT * FROM vw_Films")
    'Заполняем таблицу
    Set MSHFlexGrid1.DataSource = rs
    'Ширина колонок
    MSHFlexGrid1.ColWidth(0) = 200
    MSHFlexGrid1.ColWidth(1) = 500
    MSHFlexGrid1.ColWidth(2) = 3000
    MSHFlexGrid1.ColWidth(3) = 2000
    MSHFlexGrid1.ColWidth(4) = 1000
    MSHFlexGrid1.ColWidth(5) = 1100
    MSHFlexGrid1.ColWidth(6) = 1000
    MSHFlexGrid1.ColWidth(7) = 600
    'Курсор таблицы
    MSHFlexGrid1.SelectionMode = flexSelectionByRow
    MSHFlexGrid1.ScrollTrack = True
End Sub

Private Function FIND(ByRef sql As String) As ADODB.Recordset
   
    Screen.MousePointer = vbHourglass
   
    'Подключение к БД
    Dim cn As ADODB.Connection
    Set cn = New ADODB.Connection
    cn.Open (Soedinenie)
   
    'Параметрический запрос
    'Обработка БД на VB6 стр. 500
    Dim cm As ADODB.Command
    Dim rs As ADODB.Recordset
    Dim p As ADODB.Parameter
   
    'Зоздание и иниализация объекта Recordset
    Set rs = New ADODB.Recordset
    Set rs.ActiveConnection = cn
    'Грид поддерживает только клиентский курсор
    rs.CursorLocation = adUseClient
    rs.LockType = adLockOptimistic
    rs.CursorType = adOpenStatic
    'Создание объекта ADO command
    Set cm = New ADODB.Command
    Set cm.ActiveConnection = cn
   
    cm.CommandType = adCmdText
    cm.CommandText = sql
   
    'Выполнение команды
    rs.Open cm                  'Вместо "Set rs = cm.Execute", _
    т.к. "cm.Execute" выполняет "SP" на серверном курсоре!
   
    Set FIND = rs
   
    Set rs = Nothing            'Обязательно! Иначе - Error 7004!
   
    Screen.MousePointer = vbDefault

End Function

Public Sub Action(ByRef sql As String)
   
    Screen.MousePointer = vbHourglass
   
    'Подключение к БД
    Dim cn As ADODB.Connection
    Set cn = New ADODB.Connection
    cn.Open (Soedinenie)
   
    'Параметрический запрос
    'Обработка БД на VB6 стр. 500
    Dim cm As ADODB.Command
    Dim rs As ADODB.Recordset
    Dim p As ADODB.Parameter
   
    'Зоздание и иниализация объекта Recordset
    Set rs = New ADODB.Recordset
    Set rs.ActiveConnection = cn
    'Грид поддерживает только клиентский курсор
    rs.CursorLocation = adUseClient
    rs.LockType = adLockOptimistic
    rs.CursorType = adOpenStatic
    'Создание объекта ADO command
    Set cm = New ADODB.Command
    Set cm.ActiveConnection = cn
   
    cm.CommandType = adCmdText
    cm.CommandText = sql
   
    'Выполнение команды
    rs.Open cm                  'Вместо "Set rs = cm.Execute", _
    т.к. "cm.Execute" выполняет "SP" на серверном курсоре!
   
    Set rs = Nothing            'Обязательно! Иначе - Error 7004!
   
    Screen.MousePointer = vbDefault

End Sub

Private Sub MSHFlexGrid1_Click()
     rs.AbsolutePosition = MSHFlexGrid1.Row
End Sub

Private Sub Form_Resize()
    MSHFlexGrid1.Move 100, 800, Abs(Width - 300), Abs(Height - 1300)
End Sub

'V Связанный рекордсет*********************************************************
Private Sub cmdAdd_Click()
    frmAdd.Action = 1
    frmAdd.Show vbModal
End Sub

Private Sub cmdDel_Click()
    rs.Delete
    Set MSHFlexGrid1.DataSource = rs
    rs.AbsolutePosition = MSHFlexGrid1.Row
End Sub

Private Sub cmdEdit_Click()
    frmAdd.Action = 2
    frmAdd.Caption = "Edit"
    frmAdd.Text1 = rs(0).Value & ""
    frmAdd.Text2 = rs(1).Value & ""
    frmAdd.Text3 = rs(2).Value & ""
    frmAdd.Text4 = rs(3).Value & ""
    frmAdd.Text5 = rs(4).Value & ""
    frmAdd.Text6 = rs(5).Value & ""
    frmAdd.Show vbModal
End Sub
'A Связанный рекордсет*********************************************************

'V Не связанный рекордсет******************************************************
Private Sub cmdAdd1_Click()
    frmAdd.Action = 3
    frmAdd.Show vbModal
End Sub

Private Sub cmdDel1_Click()
    Call Action("DELETE FROM Films WHERE FilmID = " & rs(6).Value & "")
    Call cmdRefresh_Click
End Sub

Private Sub cmdEdit1_Click()
    frmAdd.Action = 4
    frmAdd.Caption = "Edit"
    frmAdd.Text1 = rs(0).Value & ""
    frmAdd.Text2 = rs(1).Value & ""
    frmAdd.Text3 = rs(2).Value & ""
    frmAdd.Text4 = rs(3).Value & ""
    frmAdd.Text5 = rs(4).Value & ""
    frmAdd.Text6 = rs(5).Value & ""
    frmAdd.Show vbModal
End Sub
'A Не связанный рекордсет******************************************************

Public Sub cmdRefresh_Click()
    Call Form_Load
End Sub

Private Sub cmdExit_Click()
    Unload Me
End Sub

'frmAdd (Форма добавления данных)
Код: Выделить всё

Public Action As Byte

Private Sub cmdExit_Click()
    Unload Me
End Sub

Private Sub cmdOK_Click()
    Dim t As String
    Select Case Action
    'V Связанный рекордсет*********************************************************
    Case 1
        'Добавление записи
        frmADO.rs.AddNew
        frmADO.rs!№ = Text1
        frmADO.rs![Название фильма] = Text2
        frmADO.rs!Актеры = Text3
        frmADO.rs!Жанр = Text4
        frmADO.rs!Примечание = Text5
        frmADO.rs!Отзыв = Text6
        frmADO.rs.Resync
        Set frmADO.MSHFlexGrid1.DataSource = frmADO.rs
        frmADO.rs.AbsolutePosition = frmADO.MSHFlexGrid1.Row
        Unload Me
    Case 2
        'Редактирование записи
        frmADO.rs!№ = Text1
        frmADO.rs![Название фильма] = Text2
        frmADO.rs!Актеры = Text3
        frmADO.rs!Жанр = Text4
        frmADO.rs!Примечание = Text5
        frmADO.rs!Отзыв = Text6
        Set frmADO.MSHFlexGrid1.DataSource = frmADO.rs
        frmADO.rs.AbsolutePosition = frmADO.MSHFlexGrid1.Row
        Unload Me
    'A Связанный рекордсет*********************************************************
    'V Не связанный рекордсет******************************************************
    Case 3
        'Добавление записи
        t = "INSERT INTO Films ("
        t = t & "№, "
        t = t & "Film, "
        t = t & "Akter, "
        t = t & "Janr, "
        t = t & "Prim, "
        t = t & "Otziv) "
        t = t & "VALUES ("
        t = t & "'" & Text1 & "', "
        t = t & "'" & Text2 & "', "
        t = t & "'" & Text3 & "', "
        t = t & "'" & Text4 & "', "
        t = t & "'" & Text5 & "', "
        t = t & "'" & Text6 & "')"
        Call frmADO.Action(t)
        'Обновление
        Call frmADO.cmdRefresh_Click
        Unload Me
    Case 4
        'Редактирование записи
        frmADO.MSHFlexGrid1.Col = 7
        t = "UPDATE Films SET "
        t = t & "№ = '" & Text1 & "', "
        t = t & "Film = '" & Text2 & "', "
        t = t & "Akter = '" & Text3 & "', "
        t = t & "Janr = '" & Text4 & "', "
        t = t & "Prim = '" & Text5 & "', "
        t = t & "Otziv = '" & Text6 & "' "
        t = t & "WHERE FilmID = " & frmADO.MSHFlexGrid1.Text
        Call frmADO.Action(t)
        'Обновление
        Call frmADO.cmdRefresh_Click
        Unload Me
    'A Не связанный рекордсет******************************************************
    End Select
End Sub
Вложения
ADO.rar
Пример
(16.96 Кб) Скачиваний: 71
С уважением, Сергей.

Dmitriy2003
Постоялец
Постоялец
 
Сообщения: 690
Зарегистрирован: 27.05.2003 (Вт) 22:47
Откуда: Deutschland

Сообщение Dmitriy2003 » 10.04.2007 (Вт) 19:38

И почему автора не устраивает UpdateBatch :?:

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 10.04.2007 (Вт) 19:43

Спасибо GSerg
Код: Выделить всё

Set rs.ActiveConnection = Nothing

То, что мне было нужно.
С уважением, Сергей.

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 10.04.2007 (Вт) 21:57

1) Правильно ли я делаю?

2) Хотелось бы сделать так, чтобы пользователь не мог ничего печатать в таблице...
Для ютого нужно было бы курсор открыть только для чтения.
Код: Выделить всё
rs.LockType = adLockReadOnly

НО, тогда нельзя будет выполнять модификацию
Код: Выделить всё

rs.Delete
frmADO.rs.AddNew

в отвязном рекордсете... Как быть?

Хватит постить простыни кода, вдвойне бессмысленные при наличии аттача
Вложения
ADO.rar
ADO
(17.37 Кб) Скачиваний: 74
С уважением, Сергей.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 10.04.2007 (Вт) 22:06

1) Сомневаюсь.

2) Есть большая разница между ReadOnly в рекордсете и ReadOnly в отображающем гриде.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

sergey-911
Постоялец
Постоялец
 
Сообщения: 545
Зарегистрирован: 17.01.2005 (Пн) 19:10

Сообщение sergey-911 » 10.04.2007 (Вт) 22:22

1) Сомневаюсь.

Почему GSerg, объясни пожалуйста, что я делаю не так?
2) Есть большая разница между ReadOnly в рекордсете и ReadOnly в отображающем гриде.

Спасибо GSerg, нашёл
Код: Выделить всё
DataGrid1.AllowUpdate = Fals
С уважением, Сергей.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 49

    TopList