Гость
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Заполнение подчиненной формы / 19 сообщений из 19, страница 1 из 1
08.06.2019, 22:28
    #39824512
wls1978
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
Доброго денечка!
Вопрос такой. Делаю уже третью форму Access + SQL по стандартному алгоритму: в заголовке формы фильтры, которые по кнопке Применить обновляют содержимое подчиненной табличной формы. Надо просто выводить записи, соответствующие условиям фильтра.
Предыдущие 2 формы работают. Но третья... просто чудеса в решете.

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

Код: vbnet
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.
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 и значение присваивается соответствующее.
...
Рейтинг: 0 / 0
09.06.2019, 20:12
    #39824647
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978, это не фильтрация, т.е. не применение фильтра
Код: vbnet
1.
 .filter="": .filteron=true


ошибка с NumSession - вполне возможно что записей слишком много, rs.count ещё не посчитан, переход на первую строку не выполняется, а в BOF значения нет . т.е. нужно бы rs.movelast, затем уже rs.count... а дальше следствие, поскольку rs.movefirst не выполнен, вполне возможно что к этому моменту rs.count посчитали, где остановились там и остались... в конце.
...
Рейтинг: 0 / 0
09.06.2019, 21:52
    #39824673
wls1978
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
alecko,
rs.movefirst есть, не написала сюда в код, прошу прощения. Но проверю, где этот movefirst - до присвоения NumSession или после. Спасибо за подсказку.
А записей на тесте всего 2, так что не может быть переполнения.

По поводу фильтра - я имею ввиду не фильтрацию источника данных, а выбор записей в базе SQL. Т.е. на форме я выставляю условия, по которым отбираю записи. Эти условия и называю фильтрами.
...
Рейтинг: 0 / 0
09.06.2019, 23:41
    #39824698
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978,
речь про эту строчку
Код: vbnet
1.
 If rs.RecordCount <> 0 Then rs.MoveFirst


имел ввиду
Код: vbnet
1.
2.
rs.movelast ' как то лучше заходит именно в подчиненных формах if rs.bof and rs.EOF then ...вместо проверки на количество записей
 If rs.RecordCount <> 0 Then rs.MoveFirst
...
Рейтинг: 0 / 0
10.06.2019, 04:12
    #39824722
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978rs.movefirst есть, не написала сюда в код, прошу прощения.избыточно, ADO без прогона записей сразу знает сколько их. Проверять лучше с помощью BOF и EOF , если оба свойства true, то набор пуст.

Зачем в коде объект Command если он не используется в дальнейшем? Нужно так
Код: vbnet
1.
2.
3.
4.
5.
6.
...
cmd.CommandType = adCmdText
s = "declare..."
cmd.CommandText=s
rs.Open cmd, CursorType:= adOpenStatic
...
...
Рейтинг: 0 / 0
10.06.2019, 04:26
    #39824723
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978
Код: vbnet
1.
If rs.RecordCount <> 0 Then rs.MoveFirst

Избыточно. После того как набор ADO открыт, он сразу на первой записи, если записи есть.

wls1978
Код: vbnet
1.
2.
3.
4.
5.
6.
        DoCmd.SetWarnings False
        s = "delete from tmp_PrikazDek where UsID = " & rs("UsID")
        DoCmd.RunSQL s
...
        DoCmd.SetWarnings True
...

Вот зачем всё мешать? не проще ли
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
        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
...


?
Код: vbnet
1.
 NumSession = Nz(rs("NumSession"),0)
...
Рейтинг: 0 / 0
10.06.2019, 04:30
    #39824725
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
Панург ADO без прогона записей сразу знает сколько ихдобавлю. В некоторых случаях вообще всегда будет -1, хотя записи будут.
...
Рейтинг: 0 / 0
10.06.2019, 04:38
    #39824726
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978Второе чудо, новое. На строчке NumSession = rs("NumSession") теперь выдает ошибку "Невозможно присвоить значение объекту". Ну, это уж вообще красота! В поле rs("NumSession") на дебаге значение 57. Чем не Integer? Откуда объекты, когда просто переменная типа Integer и значение присваивается соответствующее.Поставь перед NumSession = rs("NumSession") брекпойнт (или напиши в коде Stop ) открой окно Locals , найди в нём свой набор и посмотри чего там в первой записи в этом поле (там и тип поля будет указан).
Кстати, почему Integer ? Поставь тип Long . Жалко что-ли?
...
Рейтинг: 0 / 0
10.06.2019, 04:49
    #39824727
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
aleckoошибка с NumSession - вполне возможно что записей слишком много, rs.count ещё не посчитан, переход на первую строку не выполняется,У нас синхронные операции (поток один), потому пока набор не будет заполнен выполнение кода продолжено не будет.
...
Рейтинг: 0 / 0
12.06.2019, 03:48
    #39825629
wls1978
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
Панург
Код: vbnet
1.
 NumSession = Nz(rs("NumSession"),0)



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

А с одной добавляемой записью разобралась. Оказывается у меня в таблице ключ стоял на 2 поля, по которым вторая запись оказывалась неуникальной. Поправила ключ, записи добавляются.
...
Рейтинг: 0 / 0
12.06.2019, 03:54
    #39825630
wls1978
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
Панургwls1978Второе чудо, новое. На строчке NumSession = rs("NumSession") теперь выдает ошибку "Невозможно присвоить значение объекту". Ну, это уж вообще красота! В поле rs("NumSession") на дебаге значение 57. Чем не Integer? Откуда объекты, когда просто переменная типа Integer и значение присваивается соответствующее.Поставь перед NumSession = rs("NumSession") брекпойнт (или напиши в коде Stop ) открой окно Locals , найди в нём свой набор и посмотри чего там в первой записи в этом поле (там и тип поля будет указан).

На прилагаемой картинке видно, что значение есть, поле обзывается так же, а Integer-а мне достаточно будет выше крыши.
...
Рейтинг: 0 / 0
12.06.2019, 04:16
    #39825632
wls1978
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
В общем, разобралась в том, что если у меня переменная называется так же, как имя поля, то выдается ошибка.
А если переменная по-другому обзывается, то все присваивается, Access не считает ее объектом и прекрасно себя чувствует. Люблю Access! В чем моя ошибка? Почему нельзя переменную обозвать как и поле?
...
Рейтинг: 0 / 0
12.06.2019, 07:08
    #39825644
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978В чем моя ошибка?
Если есть поле, то к нему можно обратиться просто по его имени, к нему и обращается вместо объявленой переменной, рекордсет не обновляемый, возникает ошибка.
Мне не совсем понятно, почему приоритет отдан полю, а не переменной. По идее высший приоритет у локальных переменных, потом у переменных уровня модуля, потом переменным уровня формы и в конце - глобальным. Здесь могу ошибаться.

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

Это еще повезло, что рекордсет не обновляемый, ошибку выдало, а так и вообще было бы непонятно, почему переменная не меняется.
...
Рейтинг: 0 / 0
12.06.2019, 07:15
    #39825646
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
MrShinА чтобы такое не повторялось, нужно всегда переменным давать префиксы ипа lng, str..., переменные глобальные и уровня модуля - с дополнительным префиксом типа glng, mlng, а к полям формы обращаться только через Me, тогда подобной путаницы не будет и не придется часами выискивать, почему программа работает неправильно.+1
любят у нас найти приключений на пятую точку... буквов жалко что-ли...
...
Рейтинг: 0 / 0
12.06.2019, 07:17
    #39825647
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
добавлю.
Контролам на форме тоже давать префиксы в названия, чтобы однозначно понимать, когда обращаешься к контролу, когда к полю источника.
...
Рейтинг: 0 / 0
12.06.2019, 07:33
    #39825650
ROI
ROI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
Панургдобавлю.
Контролам на форме тоже давать префиксы в названия, чтобы однозначно понимать, когда обращаешься к контролу, когда к полю источника.
Особенно это актуально для подчиненных форм.
и потом возникают вопросы типа "не могу обновить подчиненную форму"
...
Рейтинг: 0 / 0
12.06.2019, 11:52
    #39825703
sdku
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
wls1978В общем, разобралась в том, что если у меня переменная называется так же, как имя поля, то выдается ошибка.
А если переменная по-другому обзывается, то все присваивается, Access не считает ее объектом и прекрасно себя чувствует. Люблю Access! В чем моя ошибка? Почему нельзя переменную обозвать как и поле?Ну почему нельзя-можно учитывая это из HELP:
"Оператор ! указывает, что следующий за ним элемент является элементом, определяемым пользователем (элементом семейства).
Оператор . (точка) обычно указывает, что следующий за ним элемент определен в Microsoft Access. "
-ни о каких "приоритетах" речи не идет. Но лучше, во избежание проблем, применять префиксы-как и советовали или просто не обзывать поля и переменные одинаково
Так все будет работать:
Код: vbnet
1.
NumSession = rs!NumSession


(наберите в редакторе VBA RS. и RS!-почувствуйте разницу)
...
Рейтинг: 0 / 0
12.06.2019, 14:41
    #39825754
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
sdkuТак все будет работать

Ткк проблема-то в левой части, а не в правой. VBA почему-то читает NumSession в левой части контролом, а не переменной
...
Рейтинг: 0 / 0
12.06.2019, 15:24
    #39825764
sdku
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение подчиненной формы
MrShin,
а Вы попробуйте
проблема во всем выражении,а не в какой-то его части (переменной не может быть присвоено свойство-а именно в правой части определяется что это-значение или свойство (что это значение, в данном случае должно явно указываться)
...
Рейтинг: 0 / 0
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Заполнение подчиненной формы / 19 сообщений из 19, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]