Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft Access Новый топик    Ответить
 Заполнение подчиненной формы  [new]
wls1978
Member

Откуда: Астрахань
Сообщений: 10
Доброго денечка!
Вопрос такой. Делаю уже третью форму Access + SQL по стандартному алгоритму: в заголовке формы фильтры, которые по кнопке Применить обновляют содержимое подчиненной табличной формы. Надо просто выводить записи, соответствующие условиям фильтра.
Предыдущие 2 формы работают. Но третья... просто чудеса в решете.

Делаю, может криво... но тогда прошу подсказок. Сейчас делаю так: на кнопке "Применить фильтры" (далее просто Применить) следующий код

Public cn As ADODB.Connection
Public cmd As ADODB.Command
Public NumSession As Integer
Public UsID As Integer
Dim rs As New ADODB.Recordset
Dim s As String

Set cn = New ADODB.Connection
cn.ConnectionString = "PROVIDER=SQLOLEDB; DATA SOURCE=" & srv & "; INITIAL CATALOG=" & DBName & "; INTEGRATED SECURITY=sspi;"
cn.Open
Set cmd = CreateObject("ADODB.Command") 'создаем объект команда
cmd.ActiveConnection = cn               'назначаем соединение
cmd.CommandType = adCmdText

s = "declare @NumSess smallint, @UsID int; exec dbo.sp_ProcData " _ ' далее идет список фильтров и возвращаемые значения: @@SPID и SUSER_ID()
& "@NumPrik = '" & txt_PrikNum.Value & "', @DatePrik = '" & txt_PrikDate.Value & "', @NumSession = @NumSess out, @UserID = @UsID out; select * from " & DBName & ".dbo.tmp_PrikazDek where NumSession = @NumSess and UsID = @UsID"

    rs.Open s, cn, adOpenStatic
    If rs.State <> 0 Then
        If rs.RecordCount <> 0 Then rs.MoveFirst
        NumSession = rs("NumSession")
        UsID = rs("UsID")
        DoCmd.SetWarnings False
        s = "delete from tmp_PrikazDek where UsID = " & rs("UsID")
        DoCmd.RunSQL s
        Do While Not rs.EOF
            s = "insert into tmp_PrikazDek values(" & rs("NumSession") & "," _
                & rs("UsID") & "," _
                & [перечень полей и значений] & ")"

            DoCmd.RunSQL s
            rs.MoveNext
        Loop
        DoCmd.SetWarnings True
    End If
    Me.Refresh


В подчиненной форме источник записей tmp_PrikazDek. Полям тоже присвоены источники из таблицы.

Теперь о чудесах. Начнем с того, что в подчиненную форму выводит всегда только 1 запись, первую в результате запроса. И все! Хотя по циклу бегает, запросы выполняет, ошибок не выдает никаких, но в таблице tmp_PrikazDek только одна запись и в форме соответственно. Что это за ерунда? Почему? В других аналогичных формах все заполняется...

Второе чудо, новое. На строчке NumSession = rs("NumSession") теперь выдает ошибку "Невозможно присвоить значение объекту". Ну, это уж вообще красота! В поле rs("NumSession") на дебаге значение 57. Чем не Integer? Откуда объекты, когда просто переменная типа Integer и значение присваивается соответствующее.
8 июн 19, 22:28    [21905256]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
alecko
Member

Откуда: Башкирия
Сообщений: 497
wls1978, это не фильтрация, т.е. не применение фильтра
 .filter="": .filteron=true

ошибка с NumSession - вполне возможно что записей слишком много, rs.count ещё не посчитан, переход на первую строку не выполняется, а в BOF значения нет . т.е. нужно бы rs.movelast, затем уже rs.count... а дальше следствие, поскольку rs.movefirst не выполнен, вполне возможно что к этому моменту rs.count посчитали, где остановились там и остались... в конце.
9 июн 19, 20:12    [21905507]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
wls1978
Member

Откуда: Астрахань
Сообщений: 10
alecko,
rs.movefirst есть, не написала сюда в код, прошу прощения. Но проверю, где этот movefirst - до присвоения NumSession или после. Спасибо за подсказку.
А записей на тесте всего 2, так что не может быть переполнения.

По поводу фильтра - я имею ввиду не фильтрацию источника данных, а выбор записей в базе SQL. Т.е. на форме я выставляю условия, по которым отбираю записи. Эти условия и называю фильтрами.
9 июн 19, 21:52    [21905544]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
alecko
Member

Откуда: Башкирия
Сообщений: 497
wls1978,
речь про эту строчку
 If rs.RecordCount <> 0 Then rs.MoveFirst

имел ввиду
rs.movelast ' как то лучше заходит именно в подчиненных формах if rs.bof and rs.EOF then ...вместо проверки на количество записей
 If rs.RecordCount <> 0 Then rs.MoveFirst
9 июн 19, 23:41    [21905572]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
wls1978
rs.movefirst есть, не написала сюда в код, прошу прощения.
избыточно, ADO без прогона записей сразу знает сколько их. Проверять лучше с помощью BOF и EOF, если оба свойства true, то набор пуст.

Зачем в коде объект Command если он не используется в дальнейшем? Нужно так
...
cmd.CommandType = adCmdText
s = "declare..."
cmd.CommandText=s
rs.Open cmd, CursorType:= adOpenStatic
...
10 июн 19, 04:12    [21905602]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
wls1978
If rs.RecordCount <> 0 Then rs.MoveFirst
Избыточно. После того как набор ADO открыт, он сразу на первой записи, если записи есть.

wls1978
        DoCmd.SetWarnings False
        s = "delete from tmp_PrikazDek where UsID = " & rs("UsID")
        DoCmd.RunSQL s
...
        DoCmd.SetWarnings True
...
Вот зачем всё мешать? не проще ли
        Set cn =CurrentProject.Connection
        cn.Execute "delete from tmp_PrikazDek where UsID = " & rs("UsID")
        Do Until rs.EOF
            s = "insert into tmp_PrikazDek values(" & rs("NumSession") & "," _
                & rs("UsID") & "," _
                & [перечень полей и значений] & ")"

            cn.Execute s
            rs.MoveNext
        Loop
...

?
 NumSession = Nz(rs("NumSession"),0)
10 июн 19, 04:26    [21905603]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
Панург
ADO без прогона записей сразу знает сколько их
добавлю. В некоторых случаях вообще всегда будет -1, хотя записи будут.
10 июн 19, 04:30    [21905605]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
wls1978
Второе чудо, новое. На строчке NumSession = rs("NumSession") теперь выдает ошибку "Невозможно присвоить значение объекту". Ну, это уж вообще красота! В поле rs("NumSession") на дебаге значение 57. Чем не Integer? Откуда объекты, когда просто переменная типа Integer и значение присваивается соответствующее.
Поставь перед NumSession = rs("NumSession") брекпойнт (или напиши в коде Stop) открой окно Locals, найди в нём свой набор и посмотри чего там в первой записи в этом поле (там и тип поля будет указан).
Кстати, почему Integer? Поставь тип Long. Жалко что-ли?
10 июн 19, 04:38    [21905606]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
alecko
ошибка с NumSession - вполне возможно что записей слишком много, rs.count ещё не посчитан, переход на первую строку не выполняется,
У нас синхронные операции (поток один), потому пока набор не будет заполнен выполнение кода продолжено не будет.
10 июн 19, 04:49    [21905607]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
wls1978
Member

Откуда: Астрахань
Сообщений: 10
Панург
 NumSession = Nz(rs("NumSession"),0)


То же сообщение.

А с одной добавляемой записью разобралась. Оказывается у меня в таблице ключ стоял на 2 поля, по которым вторая запись оказывалась неуникальной. Поправила ключ, записи добавляются.
12 июн 19, 03:48    [21907130]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
wls1978
Member

Откуда: Астрахань
Сообщений: 10
Панург
wls1978
Второе чудо, новое. На строчке NumSession = rs("NumSession") теперь выдает ошибку "Невозможно присвоить значение объекту". Ну, это уж вообще красота! В поле rs("NumSession") на дебаге значение 57. Чем не Integer? Откуда объекты, когда просто переменная типа Integer и значение присваивается соответствующее.
Поставь перед NumSession = rs("NumSession") брекпойнт (или напиши в коде Stop) открой окно Locals, найди в нём свой набор и посмотри чего там в первой записи в этом поле (там и тип поля будет указан).


На прилагаемой картинке видно, что значение есть, поле обзывается так же, а Integer-а мне достаточно будет выше крыши.

К сообщению приложен файл. Размер - 12Kb
12 июн 19, 03:54    [21907131]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
wls1978
Member

Откуда: Астрахань
Сообщений: 10
В общем, разобралась в том, что если у меня переменная называется так же, как имя поля, то выдается ошибка.
А если переменная по-другому обзывается, то все присваивается, Access не считает ее объектом и прекрасно себя чувствует. Люблю Access! В чем моя ошибка? Почему нельзя переменную обозвать как и поле?
12 июн 19, 04:16    [21907135]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
MrShin
Member

Откуда:
Сообщений: 1237
wls1978
В чем моя ошибка?

Если есть поле, то к нему можно обратиться просто по его имени, к нему и обращается вместо объявленой переменной, рекордсет не обновляемый, возникает ошибка.
Мне не совсем понятно, почему приоритет отдан полю, а не переменной. По идее высший приоритет у локальных переменных, потом у переменных уровня модуля, потом переменным уровня формы и в конце - глобальным. Здесь могу ошибаться.

А чтобы такое не повторялось, нужно всегда переменным давать префиксы ипа lng, str..., переменные глобальные и уровня модуля - с дополнительным префиксом типа glng, mlng, а к полям формы обращаться только через Me, тогда подобной путаницы не будет и не придется часами выискивать, почему программа работает неправильно.

Это еще повезло, что рекордсет не обновляемый, ошибку выдало, а так и вообще было бы непонятно, почему переменная не меняется.
12 июн 19, 07:08    [21907158]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
MrShin
А чтобы такое не повторялось, нужно всегда переменным давать префиксы ипа lng, str..., переменные глобальные и уровня модуля - с дополнительным префиксом типа glng, mlng, а к полям формы обращаться только через Me, тогда подобной путаницы не будет и не придется часами выискивать, почему программа работает неправильно.
+1
любят у нас найти приключений на пятую точку... буквов жалко что-ли...
12 июн 19, 07:15    [21907160]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
Панург
Member

Откуда: настоящему индейцу завсегда везде ништяк
Сообщений: 4253
добавлю.
Контролам на форме тоже давать префиксы в названия, чтобы однозначно понимать, когда обращаешься к контролу, когда к полю источника.
12 июн 19, 07:17    [21907161]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
ROI
Member

Откуда: г. Тюмень
Сообщений: 1694
Панург
добавлю.
Контролам на форме тоже давать префиксы в названия, чтобы однозначно понимать, когда обращаешься к контролу, когда к полю источника.

Особенно это актуально для подчиненных форм.
и потом возникают вопросы типа "не могу обновить подчиненную форму"
12 июн 19, 07:33    [21907164]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
sdku
Member

Откуда: Краснодар
Сообщений: 5885
wls1978
В общем, разобралась в том, что если у меня переменная называется так же, как имя поля, то выдается ошибка.
А если переменная по-другому обзывается, то все присваивается, Access не считает ее объектом и прекрасно себя чувствует. Люблю Access! В чем моя ошибка? Почему нельзя переменную обозвать как и поле?
Ну почему нельзя-можно учитывая это из HELP:
"Оператор ! указывает, что следующий за ним элемент является элементом, определяемым пользователем (элементом семейства).
Оператор . (точка) обычно указывает, что следующий за ним элемент определен в Microsoft Access. "
-ни о каких "приоритетах" речи не идет. Но лучше, во избежание проблем, применять префиксы-как и советовали или просто не обзывать поля и переменные одинаково
Так все будет работать:
NumSession = rs!NumSession

(наберите в редакторе VBA RS. и RS!-почувствуйте разницу)
12 июн 19, 11:52    [21907241]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
MrShin
Member

Откуда:
Сообщений: 1237
sdku
Так все будет работать


Ткк проблема-то в левой части, а не в правой. VBA почему-то читает NumSession в левой части контролом, а не переменной
12 июн 19, 14:41    [21907302]     Ответить | Цитировать Сообщить модератору
 Re: Заполнение подчиненной формы  [new]
sdku
Member

Откуда: Краснодар
Сообщений: 5885
MrShin,
а Вы попробуйте
проблема во всем выражении,а не в какой-то его части (переменной не может быть присвоено свойство-а именно в правой части определяется что это-значение или свойство (что это значение, в данном случае должно явно указываться)
12 июн 19, 15:24    [21907318]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft Access Ответить