Доброго времени суток, Посетитель!
|
|
|
|
|
|
|
|
|
вид форума:
|
|
|
|
| Добрый день.
Ситуация такая у меня, забыл все:
При работе в одной из форм, при выполнении из нее процедуры, необходимо из нее открыть другую пустую форму ввода
с тремя полями
Номер, Кассир, Окно.
Ввести в эти поля данные и при нажатии ОК
передать эти введенные данные в процедуру выполняемую в первой форме?
и присвоить эти данные трем переменным в этой процедуре varNum, varKassir, varOkno/
Буду очень признателен за помощь.
Спасибо! | |
|
| |
|
|
|
| Трудно сказать. В аксе есть процедуры вывода диалоговой формы, куда можно вводить данные и как-то их применять. Можно заготовить форму на таблицу и открыть ее в режиме добавления данных, или запрос с параметром [Введи значение], но в данном случае наверно как-то так:
текст процедуры.... в ней где-то вдруг так:
DoCmd.OpenForm "Форма ввода" 'открыть форму с полями желательно модальную
далее при закрытии этой формы код:
varNum=Forms![Форма ввода]!Номер
varKassir=Forms![Форма ввода]!Кассир
varOkno=Forms![Форма ввода]!Окно
Эти переменные наверно должны быть глобальными. Но требуется подумать, как сделать паузу, что бы пока вводятся данные, процедура не выполнялась дальше. Типа MsgBox открыть. Может разделить процедуру на 2 части, до открытия формы и после... Или все таки воспользоваться формами диалога. От ситуации. Может все же запускать запрос с параметром на изменение данных в таблице. | |
|
| |
|
|
|
| 1. делается форма
2. открывается в режиме Диалога
3. при нажатии на Ок форма делается "скрывается"
4. далее в коде проверяются и используются значения из полей
примерно так
DoCmd.OpenForm "frmFilters", acNormal, , , , acDialog
If IsFormLoaded("frmFilters") Then '-- если да, то построить строку параметров
Set f = Forms("frmFilters")
' Set rs = Forms("frmFilters").RecordsetClone
' pparam = ""
' If Not rs.EOF Then
' rs.MoveLast: rs.MoveFirst
' Do While Not rs.EOF
' If Nz(rs.Fields("invno").value, 0) > 0 Then pparam = pparam & "," & rs.Fields("invno").value
' rs.MoveNext
' Loop
' End If
' pparam = Mid(pparam, 2)
If DCount("[invno]", "_filter_invno") > 0 Then
pparam = "select invno from [_filter_invno]"
mw = IIf(mw <> "", mw & " and nz(invno,0) in (" & pparam & ")", "WHERE nz(invno,0) in (" & pparam & ")")
Me.capInvno.ForeColor = 16711680
Else
MsgBox "В форме 'Фильтр' не найдено ни одного инвентарного номера!"
End If
If f.isOk <> 0 Then DoCmd.Close acForm, f.Name
End If
|
| |
|
| |
|
|
|
| Что-то слишком наворочено и сложно. Процедуру мы не знаем, но должно быть несколько проще. Где Лукас | |
|
| |
|
|
|
| где наворочено?
там комменты.... ну не убрал... главное идея | |
|
| |
|
|
|
| Эх, разбаловал нас Access своими "вывернутыми наружу потрохами форм".
Идеи инкапсуляции заживо похоронены. | |
|
| |
|
|
|
| да нееее, просто это классический варьянт, а у тебя - правильный ;)
я в аксессе уже давно не пишу чего-то серьезного
использую как - быстро наваять очередную приблуду :)
| |
|
| |
|
|
|
|
... использую как - быстро наваять очередную приблуду :)
|
То есть по прямому его назначению.
Пример-то ваш, кстати сказать, довольно актуален, судя по вопросам на форумах.
Вот если сборку pparam оформить методом формы "frmFilters", было бы полезно массе народу.
| |
|
| |
|
|
|
| Так выходит, что мое направление правильное было. Даже про модальную форму?? | |
|
| |
|
|
|
| Назвать методу с модальностью формы и глобальными переменными "неправильной"
было-бы некорректно, потому как работает и довольно часто пользуется.
СилЫч подобрал правильное слово: "Классическая". | |
|
| |
|
|
|
| В модуле формы ввода:
Public Event Closed(Number As String, Cashier As String, Window As String)
Private Sub Form_Unload(Cancel As Integer)
RaiseEvent Closed(Me.txtNumber & vbNullString, Me.txtCashier & vbNullString, Me.txtWindow & vbNullString)
End Sub
|
В модуле вызывающей формы:
Private WithEvents frmIn As Form_frmInput
Private strNumber As String
Private strCashier As String
Private strWindow As String
Private Sub btn1_Click()
With New Form_frmInput
Set frmIn = .Form
.Modal = True 'по желанию
.Visible = True
End With
End Sub
Private Sub frmIn_Closed(Number As String, Cashier As String, Window As String)
strNumber = Number
strCashier = Cashier
strWindow = Window
'Debug.Print strNumber, strCashier, strWindow
Set frmIn = Nothing
End Sub
|
| |
|
| |
|
|
|
| Спасибо, парни, что откликнулись.
Пиво не позволяет сейчас вникнуть в коды.
Но, с Силычем соглашусь, я тоже более трех лет не лабал на аксе ни чего, вот и туплю.
Но, помню, что что-то было как передача через аргументы.
Но, я поступал проще вроде как щас благодаря Сылычу вспоминаю, открывал форму ввода, в нее вводились в поля данные, затем по кнопке ОК, она становилась скрытой, а уж из кода из первой формы начинал считывать ссылаясь на форму вводка, тьфу, ввода ссылаясь на нее как на открытую по имени, затем присваивал переменным данные полей скрытой формы, скрытку закрывал, и пускался код дальше в работу.
Но, вот, точно не помню, завтра буду разбираться.
Но, чую есть какой-то метод получения именно по коду в переменные. | |
|
| |
|
|
|
| Не прокатит в моем случае.
Про InputBox-ы я знаю, но они не устраивают по ряду ключевых моментов.
по тем вводимым параметрам в формее ввода придется выводить три ИмпутБокса.
Но, учитывая уровень пользования и образованности юзеров кои предположительно будут юзать данную девайсу, это будет полный пипец.
В форме ввода присутствуют: поле Номер (тупо поле ввод, куда просто вбиваются 1-2 цифры), второе - это Группа переключателей (2 переключателя), в зависимости от выбора переключателя, включаются-выключаются два комбобокса. Один комбобокс имеет ограниченный, заранее забитый список. Другой чуть хитрее, кстати, если кто поможет с запросами типа Юнион, завтра залабаю здесь вопрос, как его организовать, т.к. данные в комбобоксе втором, берутся из объединенного запроса (строится по двум-пяти полям другого запроса на выборку), SQL уж и так не знал дуже гарно, а с годами и вообще забыл.
так вот, эта форма ввода была сделана таким образом для того, чобы юзеры просто выбирали то, что есть в комбобоксах (как результат, в отличии от инпутбоксов, это минимум ошибок и очепяток, ну и, что наиболее главное, быстрота ввода, получил комбобокс фокус, список вывалился, оператор выбрала нужный пункт, без ошибок и поехала к следующему комбо). В общем, идея такая. Но, как вот вытянуть эти данные из этих полей и комбо, и передать в первую форму, примерно уж вспоминаю, но, до сих пор не до пойму, где чего не так делаю. | |
|
| |
|
|
|
| Выложи проблему в виде файла, а там всем скопом разберемся.
InputBox предложил как один из прочих предложенных мной варианта. Но все таки предпочтительнее форму с полями. Тем более с комбоксами. А может со списками даже лучше получится. | |
|
| |
|
|
|
| Гоблин, завтра выложу, постараюсь.
Тока, мне стыдновато чутка, я в свое время был просто любитель, а ща вообще все позабыл.
Сильно не смейтесь тока!
Просто когда лабаю чего-нить, боюсь потерять идею, т.е. общую работу базы, как да что да через что должно действовать, о коде не задумываюсь. | |
|
| |
|
|
|
|
| делаю так:
1. из основной формы по клику на кнопку открываю форму для ввода дополнительных данных
(если форма для ввода допданных используется для запуска нескольких процедур через OpenArgs передаю дополнительные идентификационные данные)
2. после ввода доп данных по нажатию кнопочки "Посчитать" запускается необходимая процедура (нужная в зависимости от значения OpenArgs) (тут же перед запуском процедуры можно устроить проверку на правильность заполнения нужных полей)
3. Пока форма открыта с нее считываются необходимые данные и присваиваются переменным, либо используются напрямую как значение контрола
4. далее по коду Форма ввода доп данных закрывается
(ни глобальных переменных, ни скрытых форм) | |
|
| |
|
|
|
| Просто передать значения из формы в форму просто. Здесь речь идет, как я понимаю, о приостановке выполняемого кода на время ввода данных и передаче данных переменным в модуль формы.
Не круто, но работает такой код.
В первой форме надо изменить значения x,y,z
Поля 1,2,3 для слежения за x,y,z
Во второй форме(ввода) те же поля 1,2,3
'1форма "япример1"
Option Compare Database
Private x As Long
Private y As Long
Private z As Long
Private flag As Boolean
Private Sub BtnMyProc_Click()
Dim i As Integer 'просто демонстрируем вызов окна ввода в цикле на 5-м шаге
For i = 1 To 10
flag = False
Me.Caption = "step=" & i ' следим за ходом выполнения
If i = 5 Then
Me.Caption = "На шаге " & i & " вызвали окно ввода"
DoCmd.OpenForm "япример2", , , , , acDialog
While Not flag 'ждем отработки окна ввода, flag вернется из нее
DoEvents
Wend
End If
Next i
End Sub
Private Sub Form_Open(Cancel As Integer)
x = 1: y = 2: z = 3 'для примера
MyNewValue
End Sub
Public Property Let NEWX(vx As Long)
x = vx
MyNewValue
End Property
Public Property Let NEWY(vx As Long)
y = vx
MyNewValue
End Property
Public Property Let NEWZ(vx As Long)
z = vx
MyNewValue
End Property
Public Property Let NEWFLAG(vx As Long)
flag = vx
End Property
Public Sub MyNewValue()
Поле1 = x 'показали измененные значения
Поле2 = y
Поле3 = z
End Sub
'2форма ввода "япример2"
Private Sub btnok_Click()
''следующие три строки можно повесить на события обновления соотв. полей
Forms("япример1").NEWX = (Поле1)
Forms("япример1").NEWY = (Поле2)
Forms("япример1").NEWZ = (Поле3)
'мы закончили - передаем flag
Forms("япример1").NEWFLAG = (True)
DoCmd.Close acForm, Me.Name
End Sub
Передавать переменные можно и по-другому. суть в приостановке...
Конечно, если значений для передачи много ... | |
|
| |
|
10 Кб. |
|
| Привет, парни. Спасибо, что откликнулись.
Вот, собственно код процедуры из первой формы…
(просьбо слишком не смеяться, мне главное понять что делать и как, а там подчищу да «подкрашу»)
в общем, по клику на кнопке запускается процедура:
Private Sub Кнопка16_Click()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim rs2 As DAO.Recordset
‘ВОТ ЭТИМ, НИЖЕ, переменным и хотелось бы присовить значения из формы ввода.
Dim varNum, varKassir, varOkno, varGrup, varValuta As Variant
Set db = CurrentDb
Set rs = db.OpenRecordset("tbl_Docs", dbOpenDynaset)
Set rs2 = db.OpenRecordset("tbl_Registr", dbOpenDynaset)
‘ВОТ ЗДЕСЬ, была попытка сделать по правильному и красивому, вызываю вторую ‘форму, т.е. форму ввода (приаттачу к сообщению)… собственно это то, что и ‘обсуждается сейчас нами.
'DoCmd.OpenForm frm_InpotDan, acNormal, , , acFormAdd, acDialog(varNum, varKassir, varOkno, varGrup)
‘А ВОТ ТАК, было изначально, но это так же было сделано, мол, щас пусть так, потом ‘сделаю красиво. Но, импутбоксы не устраивают абсолютно, т.к. во-первых есть уже ‘списки, в кои вводить не надо и кои присутствуют в форме ввода, во-вторых, юзеры ‘имеют свойство ошибатсья при вводе…
‘Собственно, сами переменные, и кривой способ присвоить им значения.
varNum = InputBox("Введите номер документа!", "Ввод номера документа")
varKassir = InputBox("Введите ФИО кассира!", "Ввод нового кассира")
varValuta = IIf(Me.RubUsd.Value = "Рубли", "Рублям", "Валюте")
‘ну, а далее поехали добавлять в таблицу….
With rs
.AddNew
![ID] = Me.ID_DOC.Value
![Name] = "Оттиск штампа для папки кассовых документов"
![OKVKU] = Me.KKO.Value
![DateResive] = Me.DateResive.Value
![RubUsd] = Me.RubUsd.Value
![Num] = varNum
![Kassir] = varKassir
![Status] = "Документ отсутствует"
![Messeg] = "Отсутствует оттиск штампа для папки кассовых документов за " & Me.DateDoc.Value & " по " & varValuta & ", по кассиру: " & varKassir
![Isp] = True
.Update
End With
rs.Close
With rs2
.FindFirst "[ID_DOC] = '" & Me![ID_DOC] & "'"
.Edit
![Status] = "В обработке"
.Update
End With
rs2.Close
Set db = Nothing
Me.frm_Docs.Requery
End Sub | |
|
| |
|
13 Кб. |
|
|
‘А ВОТ ТАК, было изначально, но это так же было сделано, мол, щас пусть так, потом ‘сделаю красиво. Но, импутбоксы не устраивают абсолютно, т.к. во-первых есть уже ‘списки, в кои вводить не надо и кои присутствуют в форме ввода, во-вторых, юзеры ‘имеют свойство ошибатсья при вводе…
‘Собственно, сами переменные, и кривой способ присвоить им значения.
varNum = InputBox("Введите номер документа!", "Ввод номера документа")
varKassir = InputBox("Введите ФИО кассира!", "Ввод нового кассира")
varValuta = IIf(Me.RubUsd.Value = "Рубли", "Рублям", "Валюте")
|
вот вместо этого и вставляй кусочек моего кода где вместо поле... пиши свои var... и в свойствах поменяй x,y,z, ha свои var...
Что б легче разобраться см. пример. | |
|
| |
|
|
|
| Ага, Дядя Федор, спасибо, буду разбираться.
Отдельное спасибо за пример! | |
|
| |
|
|
|
| Дядя Федор,
а нафига там цикл
...
DoCmd.OpenForm "япример2", , , , , acDialog
While Not flag
DoEvents
Wend
...
|
если форма открывается в диалоге?
А здесь нет проверки на "открытость" формы:
Private Sub btnok_Click()
Forms("япример1").NEWX = (Поле1)
Forms("япример1").NEWY = (Поле2)
Forms("япример1").NEWZ = (Поле3)
Forms("япример1").NEWFLAG = (True)
DoCmd.Close acForm, Me.Name
End Sub
|
И при самостоятельном открытии-закрытии правомерно ругается.
Ссылки на форму через коллекцию Forms лучше не пользовать,
потому как в случае создания нестандартного экземпляра класса формы будет ошибка при общении.
При многократном обращении к мемберам объекта, следует создавать ссылку на объект, для ускорения работы кода.
И здесь: Forms("япример1").NEW... = (Поле...) будет ошибка, если введенные данные не смогут преобразоваться к Long(в данном примере) или данные не будут введены вообще. | |
|
| |
|
|
|
| Круто.
Разобраться жизни не хватит.
А как форму на открытость проверить. Бывает надо очень. Ну типа
if Forms!Форма.open=true then
...
else
...
end if | |
|
| |
|
|
|
|
Public Function adhIsOpen( _
strName As String, _
Optional lngObjectType As AcObjectType = acForm) As Boolean
' Returns True if strName is open, False otherwise.
' Assume the caller wants to know about a form.
' From Access 2002 Desktop Developer's Handbook
' by Litwin, Getz, and Gunderloy (Sybex)
' Copyright 2001. All rights reserved.
adhIsOpen = (SysCmd(acSysCmdGetObjectState, _
lngObjectType, strName) <> 0)
End Function
|
| |
|
| |
|
|
|
| Во бин. Функция.
Спасибо. | |
|
| |
|
|
|
|
Дядя Федор,
а нафига там цикл
|
Цикл для примера!!!!!
см. Dim i As Integer 'просто демонстрируем вызов окна ввода в цикле на 5-м шаге
убери этот фрагмент
While Not flag
DoEvents
Wend
- цикл продолжает выполняться - см. демонстрацию caption.
т.е. и пример SONARA пойдет дальше не дожидаясь ввода.
А задача приостановить выполнение программы пока не будут введены данные.
По-поводу возможной некорректности ввода согласен. Но этот пример просто пример. Без полного анализа | |
|
| |
|
|
|
| Вот этот цикл:
While Not flag
DoEvents
Wend
бессмысленный, потому как перед ним форма открывается в режиме диалога,
при этом выполнение кода останавливается до момента сокрытия/закрытия формы.
Его можно смело выкидывать. | |
|
| |
|
|
|
| Согласен. Ступил. Вот если не диалог, тогда... | |
|
| |
|
|
|
|
... Вот если не диалог, тогда...
|
Тогда этот цикл загрузит оба процессора на 50 % и процессор будет работать как утюг,
исключительно на выделение тепла. | |
|
| |
|
|
|
| Мда уж, а ларчик просто открывался....
Помог чутка Силыч.
Из главной формы вызываю форму ввода, ввожу данные, по кнопке ОК, сворачиваю её
и уже из главной по семейству Forms считываю данные с полей...
DoCmd.OpenForm ("frm_InputDan"), acNormal, , , acFormAdd, acDialog
varNum = Forms![frm_InputDan]![Поле0].Value
varKassir = Forms![frm_InputDan]![ctl_Kassir].Value
varGrup = Forms![frm_InputDan]![ctl_Grup].Value
varValuta = IIf(Me.RubUsd.Value = "Рубли", "Рублям", "Валюте") | |
|
| |
|
|
|
|
...
varNum = Forms![frm_InputDan]![Поле0].Value
varKassir = Forms![frm_InputDan]![ctl_Kassir].Value
varGrup = Forms![frm_InputDan]![ctl_Grup].Value
|
автор: Lukas (10.08.2010 в 17:10)
....
А здесь нет проверки на "открытость" формы:
...
При многократном обращении к мемберам объекта, следует создавать ссылку на объект, для ускорения работы кода.
|
Опять по граблям? | |
|
| |
|
|
|
| Дык. Мы обсуждаем способы передачи значений переменным в форме, а не законченный проект.
Так надо еще проверку на ошибки сделать и т.п.
И все же передача через Property кажется мне предпочтительнее (дело вкуса). | |
|
| |
|
|
|
|
Мы обсуждаем способы передачи значений переменным в форме
|
Да. Именно поэтому мы обсуждаем недостатки/достоинства вариантов.
Мне НЕ нравится:
1. Когда класс вызываемой формы "ДОЛЖЕН" куда-то что-то "навязывать" (возвращать).
а. Этого "Куда-то" уже может и не быть. (обязательна проверка)
б. Этому "куда-то" возвращаемые "что-то" уже могут быть не интересны. (фиг проверишь)
Альтернатива: Генерировать события, возвращающие значения. Какому объекту интересно, тот подписался и слушает их.
2. Когда в классе вызываемой формы "жестко" прописана вызывающая форма.
а. Я, например, должен вызывать Вызываемую форму из нескольких вызывающих форм.
Как в этом случае определить, "кому" сейчас возвращать значения? Перебирать которая из них
открыта? Так все могут быть открыты, да еще и по нескольку раз нестандартными экземплярами.
б. Вызывающая форма открыта нестандартным экземпляром, тогда ссылки через коллекцию Forms будут давать ошибки.
Альтернативы: 1. см .п.1
2. При открытии "цеплять" ссылку на активную форму/контрол. (Формы-календари, калькуляторы и т.п.)
И все же передача через Property кажется мне предпочтительнее
|
Ну, как известно, публичная переменная, объявленная на уровне модуля, является его свойством.
Другое дело, что в процедуре свойств можно описать дополнительные проверки и прочая, так что в этом плане, конечно, процедуры свойств предпочтительнее, хотя и "тормознутее" просто переменных. | |
|
| |
|
|
|
| Исчерпывающий анализ! | |
|
| |
HiProg.com - Технологии программирования
|