Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Получить данные из другой формы...
 
 автор: SONAR   (09.08.2010 в 17:24)   личное сообщение
 
 

Добрый день.
Ситуация такая у меня, забыл все:
При работе в одной из форм, при выполнении из нее процедуры, необходимо из нее открыть другую пустую форму ввода
с тремя полями
Номер, Кассир, Окно.
Ввести в эти поля данные и при нажатии ОК
передать эти введенные данные в процедуру выполняемую в первой форме?
и присвоить эти данные трем переменным в этой процедуре varNum, varKassir, varOkno/
Буду очень признателен за помощь.
Спасибо!

  Ответить  
 
 автор: Гоблин   (09.08.2010 в 18:14)   личное сообщение
 
 

Трудно сказать. В аксе есть процедуры вывода диалоговой формы, куда можно вводить данные и как-то их применять. Можно заготовить форму на таблицу и открыть ее в режиме добавления данных, или запрос с параметром [Введи значение], но в данном случае наверно как-то так:
текст процедуры.... в ней где-то вдруг так:
DoCmd.OpenForm "Форма ввода" 'открыть форму с полями желательно модальную
далее при закрытии этой формы код:
varNum=Forms![Форма ввода]!Номер
varKassir=Forms![Форма ввода]!Кассир
varOkno=Forms![Форма ввода]!Окно

Эти переменные наверно должны быть глобальными. Но требуется подумать, как сделать паузу, что бы пока вводятся данные, процедура не выполнялась дальше. Типа MsgBox открыть. Может разделить процедуру на 2 части, до открытия формы и после... Или все таки воспользоваться формами диалога. От ситуации. Может все же запускать запрос с параметром на изменение данных в таблице.

  Ответить  
 
 автор: Силblч   (09.08.2010 в 18:22)   личное сообщение
 
 

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

  Ответить  
 
 автор: Гоблин   (09.08.2010 в 18:28)   личное сообщение
 
 

Что-то слишком наворочено и сложно. Процедуру мы не знаем, но должно быть несколько проще. Где Лукас

  Ответить  
 
 автор: Силblч   (09.08.2010 в 18:33)   личное сообщение
 
 

где наворочено?
там комменты.... ну не убрал... главное идея

  Ответить  
 
 автор: Lukas   (09.08.2010 в 18:48)   личное сообщение
 
 

Эх, разбаловал нас Access своими "вывернутыми наружу потрохами форм".
Идеи инкапсуляции заживо похоронены.

  Ответить  
 
 автор: Силblч   (09.08.2010 в 18:53)   личное сообщение
 
 

да нееее, просто это классический варьянт, а у тебя - правильный ;)
я в аксессе уже давно не пишу чего-то серьезного
использую как - быстро наваять очередную приблуду :)

  Ответить  
 
 автор: Lukas   (09.08.2010 в 19:09)   личное сообщение
 
 


... использую как - быстро наваять очередную приблуду :)


То есть по прямому его назначению.

Пример-то ваш, кстати сказать, довольно актуален, судя по вопросам на форумах.
Вот если сборку pparam оформить методом формы "frmFilters", было бы полезно массе народу.

  Ответить  
 
 автор: Гоблин   (09.08.2010 в 19:25)   личное сообщение
 
 

Так выходит, что мое направление правильное было. Даже про модальную форму??

  Ответить  
 
 автор: Lukas   (09.08.2010 в 19:39)   личное сообщение
 
 

Назвать методу с модальностью формы и глобальными переменными "неправильной"
было-бы некорректно, потому как работает и довольно часто пользуется.
СилЫч подобрал правильное слово: "Классическая".

  Ответить  
 
 автор: Lukas   (09.08.2010 в 18:35)   личное сообщение
 
 

В модуле формы ввода:

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

  Ответить  
 
 автор: SONAR   (09.08.2010 в 20:32)   личное сообщение
 
 

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

  Ответить  
 
 автор: SONAR   (09.08.2010 в 20:45)   личное сообщение
 
 

Не прокатит в моем случае.
Про InputBox-ы я знаю, но они не устраивают по ряду ключевых моментов.
по тем вводимым параметрам в формее ввода придется выводить три ИмпутБокса.
Но, учитывая уровень пользования и образованности юзеров кои предположительно будут юзать данную девайсу, это будет полный пипец.
В форме ввода присутствуют: поле Номер (тупо поле ввод, куда просто вбиваются 1-2 цифры), второе - это Группа переключателей (2 переключателя), в зависимости от выбора переключателя, включаются-выключаются два комбобокса. Один комбобокс имеет ограниченный, заранее забитый список. Другой чуть хитрее, кстати, если кто поможет с запросами типа Юнион, завтра залабаю здесь вопрос, как его организовать, т.к. данные в комбобоксе втором, берутся из объединенного запроса (строится по двум-пяти полям другого запроса на выборку), SQL уж и так не знал дуже гарно, а с годами и вообще забыл.
так вот, эта форма ввода была сделана таким образом для того, чобы юзеры просто выбирали то, что есть в комбобоксах (как результат, в отличии от инпутбоксов, это минимум ошибок и очепяток, ну и, что наиболее главное, быстрота ввода, получил комбобокс фокус, список вывалился, оператор выбрала нужный пункт, без ошибок и поехала к следующему комбо). В общем, идея такая. Но, как вот вытянуть эти данные из этих полей и комбо, и передать в первую форму, примерно уж вспоминаю, но, до сих пор не до пойму, где чего не так делаю.

  Ответить  
 
 автор: Гоблин   (09.08.2010 в 20:59)   личное сообщение
 
 

Выложи проблему в виде файла, а там всем скопом разберемся.
InputBox предложил как один из прочих предложенных мной варианта. Но все таки предпочтительнее форму с полями. Тем более с комбоксами. А может со списками даже лучше получится.

  Ответить  
 
 автор: SONAR   (09.08.2010 в 21:19)   личное сообщение
 
 

Гоблин, завтра выложу, постараюсь.
Тока, мне стыдновато чутка, я в свое время был просто любитель, а ща вообще все позабыл.
Сильно не смейтесь тока!
Просто когда лабаю чего-нить, боюсь потерять идею, т.е. общую работу базы, как да что да через что должно действовать, о коде не задумываюсь.

  Ответить  
 
 автор: Гоблин   (09.08.2010 в 23:13)   личное сообщение
 
 

я в свое время был просто любитель, а ща вообще все позабыл...

Я в настоящее время просто любитель, да и никогда ничего не знал в программировании.

Выкладывай, не я, так другие помогут советом.

  Ответить  
 
 автор: snipe   (10.08.2010 в 04:56)   личное сообщение
 
 

делаю так:
1. из основной формы по клику на кнопку открываю форму для ввода дополнительных данных
(если форма для ввода допданных используется для запуска нескольких процедур через OpenArgs передаю дополнительные идентификационные данные)
2. после ввода доп данных по нажатию кнопочки "Посчитать" запускается необходимая процедура (нужная в зависимости от значения OpenArgs) (тут же перед запуском процедуры можно устроить проверку на правильность заполнения нужных полей)
3. Пока форма открыта с нее считываются необходимые данные и присваиваются переменным, либо используются напрямую как значение контрола
4. далее по коду Форма ввода доп данных закрывается
(ни глобальных переменных, ни скрытых форм)

  Ответить  
 
 автор: Дядя Федор   (10.08.2010 в 08:02)   личное сообщение
 
 

Просто передать значения из формы в форму просто. Здесь речь идет, как я понимаю, о приостановке выполняемого кода на время ввода данных и передаче данных переменным в модуль формы.
Не круто, но работает такой код.
В первой форме надо изменить значения 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

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

  Ответить  
 
 автор: SONAR   (10.08.2010 в 15:21)   личное сообщение
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

  Ответить  
 
 автор: Дядя Федор   (10.08.2010 в 16:13)   личное сообщение
13 Кб.
 
 


‘А ВОТ ТАК, было изначально, но это так же было сделано, мол, щас пусть так, потом ‘сделаю красиво. Но, импутбоксы не устраивают абсолютно, т.к. во-первых есть уже ‘списки, в кои вводить не надо и кои присутствуют в форме ввода, во-вторых, юзеры ‘имеют свойство ошибатсья при вводе…
‘Собственно, сами переменные, и кривой способ присвоить им значения.
varNum = InputBox("Введите номер документа!", "Ввод номера документа")
varKassir = InputBox("Введите ФИО кассира!", "Ввод нового кассира")
varValuta = IIf(Me.RubUsd.Value = "Рубли", "Рублям", "Валюте")



вот вместо этого и вставляй кусочек моего кода где вместо поле... пиши свои var... и в свойствах поменяй x,y,z, ha свои var...
Что б легче разобраться см. пример.

  Ответить  
 
 автор: SONAR   (10.08.2010 в 16:46)   личное сообщение
 
 

Ага, Дядя Федор, спасибо, буду разбираться.
Отдельное спасибо за пример!

  Ответить  
 
 автор: Lukas   (10.08.2010 в 17:10)   личное сообщение
 
 

Дядя Федор,
а нафига там цикл
...
    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(в данном примере) или данные не будут введены вообще.

  Ответить  
 
 автор: Гоблин   (10.08.2010 в 22:36)   личное сообщение
 
 

Круто.
Разобраться жизни не хватит.
А как форму на открытость проверить. Бывает надо очень. Ну типа
if Forms!Форма.open=true then
...
else
...
end if

  Ответить  
 
 автор: Lukas   (10.08.2010 в 23:29)   личное сообщение
 
 


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

  Ответить  
 
 автор: Гоблин   (11.08.2010 в 00:00)   личное сообщение
 
 

Во бин. Функция.
Спасибо.

  Ответить  
 
 автор: Дядя Федор   (11.08.2010 в 08:10)   личное сообщение
 
 


Дядя Федор,
а нафига там цикл


Цикл для примера!!!!!
см. Dim i As Integer 'просто демонстрируем вызов окна ввода в цикле на 5-м шаге
убери этот фрагмент
While Not flag
DoEvents
Wend
- цикл продолжает выполняться - см. демонстрацию caption.
т.е. и пример SONARA пойдет дальше не дожидаясь ввода.

А задача приостановить выполнение программы пока не будут введены данные.
По-поводу возможной некорректности ввода согласен. Но этот пример просто пример. Без полного анализа

  Ответить  
 
 автор: Lukas   (11.08.2010 в 11:43)   личное сообщение
 
 

Вот этот цикл:
While Not flag
DoEvents
Wend
бессмысленный, потому как перед ним форма открывается в режиме диалога,
при этом выполнение кода останавливается до момента сокрытия/закрытия формы.
Его можно смело выкидывать.

  Ответить  
 
 автор: Дядя Федор   (11.08.2010 в 14:38)   личное сообщение
 
 

Согласен. Ступил. Вот если не диалог, тогда...

  Ответить  
 
 автор: Lukas   (11.08.2010 в 18:02)   личное сообщение
 
 


... Вот если не диалог, тогда...


Тогда этот цикл загрузит оба процессора на 50 % и процессор будет работать как утюг,
исключительно на выделение тепла.

  Ответить  
 
 автор: SONAR   (16.08.2010 в 11:11)   личное сообщение
 
 

Мда уж, а ларчик просто открывался....
Помог чутка Силыч.


Из главной формы вызываю форму ввода, ввожу данные, по кнопке ОК, сворачиваю её
и уже из главной по семейству 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 = "Рубли", "Рублям", "Валюте")

  Ответить  
 
 автор: Lukas   (16.08.2010 в 12:10)   личное сообщение
 
 


...
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)
....
А здесь нет проверки на "открытость" формы:
...
При многократном обращении к мемберам объекта, следует создавать ссылку на объект, для ускорения работы кода.


Опять по граблям?

  Ответить  
 
 автор: Дядя Федор   (17.08.2010 в 07:52)   личное сообщение
 
 

Дык. Мы обсуждаем способы передачи значений переменным в форме, а не законченный проект.
Так надо еще проверку на ошибки сделать и т.п.
И все же передача через Property кажется мне предпочтительнее (дело вкуса).

  Ответить  
 
 автор: Lukas   (17.08.2010 в 12:00)   личное сообщение
 
 


Мы обсуждаем способы передачи значений переменным в форме


Да. Именно поэтому мы обсуждаем недостатки/достоинства вариантов.

Мне НЕ нравится:
1. Когда класс вызываемой формы "ДОЛЖЕН" куда-то что-то "навязывать" (возвращать).
а. Этого "Куда-то" уже может и не быть. (обязательна проверка)
б. Этому "куда-то" возвращаемые "что-то" уже могут быть не интересны. (фиг проверишь)
Альтернатива: Генерировать события, возвращающие значения. Какому объекту интересно, тот подписался и слушает их.
2. Когда в классе вызываемой формы "жестко" прописана вызывающая форма.
а. Я, например, должен вызывать Вызываемую форму из нескольких вызывающих форм.
Как в этом случае определить, "кому" сейчас возвращать значения? Перебирать которая из них
открыта? Так все могут быть открыты, да еще и по нескольку раз нестандартными экземплярами.
б. Вызывающая форма открыта нестандартным экземпляром, тогда ссылки через коллекцию Forms будут давать ошибки.
Альтернативы: 1. см .п.1
2. При открытии "цеплять" ссылку на активную форму/контрол. (Формы-календари, калькуляторы и т.п.)


И все же передача через Property кажется мне предпочтительнее


Ну, как известно, публичная переменная, объявленная на уровне модуля, является его свойством.
Другое дело, что в процедуре свойств можно описать дополнительные проверки и прочая, так что в этом плане, конечно, процедуры свойств предпочтительнее, хотя и "тормознутее" просто переменных.

  Ответить  
 
 автор: Дядя Федор   (17.08.2010 в 12:49)   личное сообщение
 
 

Исчерпывающий анализ!

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList