Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Помогите с foxpro / 15 сообщений из 15, страница 1 из 1
23.05.2006, 22:31
    #33746915
Алексей1986
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Допустим есть БД гостиница примерно такая, какая на фотке
В форме для таблицы регистрация выбираем с помощью combo box'ов номер, клиента и служащего.
Допустим в одном номере все места буду заняты, тогда по идее выбрать его нельзя
Как это возможно реализовать ?
Сделал небольшой селект, который выдает полностью заполненые номера :
SELECT COUNT(Registration.nomer_id) AS kol, Nomers.nomer_number;
FROM db!nomers INNER JOIN db!registration ;
ON Nomers.nomer_id = Registration.nomer_id;
GROUP BY Registration.nomer_id;
INTO TABLE q2.dbf


SELECT DISTINCT Nomers.nomer_number;
FROM db!nomers, q2;
WHERE Q2.nomer_numb = Nomers.nomer_number;
AND Q2.kol = Nomers.nomer_quantity;
INTO TABLE q4.dbf

Теперь есть табличка с полносью заполненными номера, как сделать так чтобы в форме регистрации их нельзя было выбирать ?
...
Рейтинг: 0 / 0
24.05.2006, 00:30
    #33747020
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
1) Указывай номер версии FoxPro. В 9 версии синтаксис Select-SQL был значительно расширен. То, что можно реализовать в 9 одним запросом в младших версиях надо делать через несколько запросов.

2) Промежуточные результаты - это временные данные. Поэтому нет никакой необходимости сохранять их в постоянных таблицах. Используй курсоры

Код: plaintext
SELECT ... FROM ... INTO CURSOR q2 NOFILTER

Курсор - это та же таблица, только временная. Она автоматически будет удалена в момент закрытия.

3) Надо уточнить, что именно ты хочешь получить в результате:

а) Чтобы полностью заполненные номера были в списке, но их нельзя было выбрать
б) Чтобы полностью заполненные номера вообще не отображались в списке

Предположим, что речь идет о первом варианте.

Если в качестве источника данных для раскрывающегося списка ComboBox используется массив (Combo.RowSourceType = 5), то сделать отдельный элемент списка недоступным можно добавить перед текстом отображаемого элемента специальный служебный символ "\"

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

Результат запроса запишем сразу в массив, который будет являтся источником данных для ComboBox. Чтобы это массив был виден в момент использования в ComboBox его следует оформить как свойство формы.

В дизайнере формы пункт меню Form - New Property. В качестве имени свойства следует написать

Код: plaintext
aCombo[ 1 , 1 ]

Указание размерности как раз и говорит о том, что данное свойство - это массив.

Теперь в событии INIT-формы пишем примерно такой код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SELECT ;
	Nomers.nomer_number, ;
	Nomers.nomer_quantity - COUNT(Registration.nomer_id), ;
	Nomers.nomer_id ;
INTO ARRAY ThisForm.aCombo ;
FROM Nomers ;
LEFT JOIN registration ON Nomers.nomer_id = Registration.nomer_id ;
GROUP BY ;
	Nomers.nomer_number, ;
	Nomers.nomer_quantity, ;
	Nomers.nomer_id ;
ORDER BY ;
	Nomers.nomer_number

* Устанавливаю признак недоступности элемента списка
LOCAL lnI
FOR lnI =  1  TO ALEN(ThisForm.aCombo, 1 )
	IF ThisForm.aCombo[m.lnI, 2 ] =  0 
		ThisForm.aCombo[m.lnI, 1 ] = "\" + ThisForm.aCombo[m.lnI, 1 ]
	ENDIF
ENDFOR

Настройки ComboBox на форме будут примерно такими (можно там же в INIT-формы)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
* Если настройки делаются напрямую в дизайнере, то кавычки не нужны

ThisForm.ComboBox.BoundColumn =  3 
ThisForm.ComboBox.BoundTo = .T.  && если Nomers.nomer_id - это число
ThisForm.ComboBox.ColumnCount =  3 
ThisForm.ComboBox.ColumnWidths = "100,50,0"
ThisForm.ComboBox.RowSource = "ThisForm.aCombo"
ThisForm.ComboBox.RowSourceType =  5 

В раскрывающемся списке ComboBox будут видны 2 столбца: первый - номер номера, второй - количество свободных мест в номере.

Если количество свободных мест равно 0, то данный элемент ComboBox будет отображен светло серым цветом и недоступен для выбора.

В качестве выбранного значения будет использовано содержимое третьего столбца массива. Но его не будет видно, поскольку его ширина указана как 0. Отображаться как выбранное значение будет собственно номер.
...
Рейтинг: 0 / 0
28.05.2006, 20:57
    #33757020
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Владимир, сделал как вы написали, создал свойство aCombo[1,1] , в методе другого combo InteractiveChange прописал
Код: plaintext
1.
2.
3.
SELECT наименов_оборудования;
from sofac!наименов_оборуд;
WHERE тип_оборудов.id_типа_оборудования = наименов_оборуд.id_типа_оборуд;
into ARRAY thisform.acombo
сделал настройки combobox (в дизайнере):
ThisForm.ComboBox.RowSource = "ThisForm.aCombo"
ThisForm.ComboBox.RowSourceType = 5
и пробывал менять BoundColumn, BoundTo (без результатно)
у меня combo выводит не весь массив, а только первое значение из него
в дебаггере смотрел, массив заполнен верными данными.
Буду очень благодарен, если подскажите, где я что не указал.

С уважением, Михаил.
...
Рейтинг: 0 / 0
29.05.2006, 10:51
    #33757578
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
1) Если Вы динамически меняете содержимое раскрываемого списка ComboBox в процессе работы формы в зависимости от настроек других объектов, от после смены источника данных раскрывающегося списка его надо обновить вызвав метод Requery() самого ComboBox

ComboBox.Requery()

2) Использование события InteractiveChange для ComboBox практического смысла не имеет.

Это событие призвано отлавливать изменение текста в окне ввода. Но для ComboBox этот текст всего-лишь некий "ключ" облегчающий выбор из раскрывающегося списка. Но ни в коем случае не само выбранное значение. Факт завершения выбора в ComboBox фиксируется только в событии Valid. Там и надо делать перезапрос.

Кроме того, следует понимать, что если в результате работы команды Select-SQL не будет выбрано ни одного значения (системная переменная _TALLY=0), то указанный массив вообще не изменится. Чтобы предусмотреть эту возможность код пишут примерно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT наименов_оборудования;
from sofac!наименов_оборуд;
WHERE тип_оборудов.id_типа_оборудования = наименов_оборуд.id_типа_оборуд;
into ARRAY thisform.acombo

IF _TALLY =  0 
	DIMENSION thisform.acombo( 1 , 2 )
	thisform.acombo[ 1 , 1 ] = "\Ничего нет"
	thisform.acombo[ 1 , 2 ] =  0 
ENDIF

ThisForm.ComboBox.Requery()
...
Рейтинг: 0 / 0
31.05.2006, 17:54
    #33764272
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Здраствуйте!
ВладимирМ, спасибо за подробный ответ, вставил код, пример которого вы привели, с "пустой выборкой" разобрался.
Но вот с тем, что комбо показывает только первый элемент, нет... Код перенес в Valid.

С уважением, Михаил.
...
Рейтинг: 0 / 0
31.05.2006, 17:58
    #33764292
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
пардон, погорячился :)
все работает, просто Requery() не тому комбо сделал...

С уважением, Михаил.
...
Рейтинг: 0 / 0
31.05.2006, 18:07
    #33764323
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Можно еще вопрос по combobox'у? :)
На форме есть текстбоксы и комбобоксы для добавления людей в таблицу.
Так вот, как правильно и с наименьшими усилиями (строчками кода) написать проверку на кнопке "Добавить" что все поля заполнены? Делать вложенный if, или есть что по разумнее?

С уважением, Михаил.
...
Рейтинг: 0 / 0
31.05.2006, 19:02
    #33764444
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
По сути, только вложенные if. Точнее, последовательные. Примерно так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
LOCAL lcMessageText
lcMessageText = ""

IF EMPTY(ThisForm.TextBox1.Value) = .T.
	lcMessageText = m.lcMessageText + CHR( 13 ) + "TextBox1"
ENDIF
IF EMPTY(ThisForm.TextBox2.Value) = .T.
	lcMessageText = m.lcMessageText + CHR( 13 ) + "TextBox2"
ENDIF
...
IF EMPTY(m.lcMessageText) = .F.
	lcMessageText = "Заполните поля:" + m.lcMessageText 
	MessageBox(m.lcMessageText)
ENDIF

RETURN EMPTY(m.lcMessageText)

Тут вместо TextBox в символьную строку lcMessageText надо записывать "нормальные" названия того, что было не заполнено.

При любом раскладе пользователю надо будет сообщить, что именно он не заполнил. Без перебора ты этот список не получишь. Кроме того, желательно сразу установить фокус в первый не заполненный объект.

Я выделяю процедуру проверки в отдельный метод, поэтому здесь такой странный RETURN. По возвращаемому значению определяю, следует ли продолжать процедуру сохранения или же надо ее прервать, чтобы пользователь заполнил не заполненные поля.
...
Рейтинг: 0 / 0
31.05.2006, 20:15
    #33764553
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Спасибо!
Попробую сделать )))
...
Рейтинг: 0 / 0
31.05.2006, 20:39
    #33764577
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Владимир, напишите пожалуста пример того, как на клике кнопки "Добавить" проверить, что возвращает метод "проверки"... Я не силен в программировании :(

С уважением, Михаил.
...
Рейтинг: 0 / 0
01.06.2006, 16:30
    #33766567
Pavelik
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Здорова всем!
Короче с FoxPro не занимался больше года и все основы практически забыл.
Для начала взался связывать две таблицы и что-то не прошло и не получилось.
На простом примере прошу объяснить мне как связать 2 таблицы и заполнить их! Если не хотите тратить время так и напишите, И я тогда пойду дальше!
Заранее спасибо!
Доки на диске пока не моего уровня, там шпаргалка для "тех кто вкурсе", а в netе замахался путевую ламерскую доку икать!
...
Рейтинг: 0 / 0
01.06.2006, 17:46
    #33766910
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
ВладимирМЯ выделяю процедуру проверки в отдельный метод, поэтому здесь такой странный RETURN. По возвращаемому значению определяю, следует ли продолжать процедуру сохранения или же надо ее прервать, чтобы пользователь заполнил не заполненные поля.
каким кодом, хоть примерно, это можно реализовать на клике кнопки? т.е. как проверять?

С уважением, Михаил.
...
Рейтинг: 0 / 0
01.06.2006, 17:48
    #33766922
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
метод (у формы) с вашим кодом я назвал emptydata...

с уважением, Михаил.
...
Рейтинг: 0 / 0
01.06.2006, 18:35
    #33767120
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Adic ВладимирМЯ выделяю процедуру проверки в отдельный метод, поэтому здесь такой странный RETURN. По возвращаемому значению определяю, следует ли продолжать процедуру сохранения или же надо ее прервать, чтобы пользователь заполнил не заполненные поля.
каким кодом, хоть примерно, это можно реализовать на клике кнопки? т.е. как проверять?

Ну, на клике кнопки "Сохранить" что-то вроде такого

Код: plaintext
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.
LOCAL llSuccess
llSuccess = .T.

* Проверка факта изменения данных
* Если данные не менялись, нет смысла их сохранять
IF llSuccess = .T.
	llSuccess = ThisForm.IsModifiedData()
ENDIF

* Проверка корректности заполнения данных
* Не только пустые, но и допустимые значения
IF llSuccess = .T.
	llSuccess = ThisForm.IsCorrectData()
ENDIF

* Заполнение служебных данных, недоступных пользователю
IF llSuccess = .T.
	llSuccess = ThisForm.CreateServiceData()
ENDIF

* Собственно сохранение данных без контроля корректности
IF llSuccess = .T.
	llSuccess = ThisForm.SaveData()
ENDIF

* Обновление "картинки" на данной и связанных формах
IF llSuccess = .T.
	llSuccess = ThisForm.RefreshData()
ENDIF

Все упомянутые здесь методы - это мои собственные (не стандартные) методы. В каждом из них выполняется соответсвующее действие и по результату возвращается .T. или .F. что и позволяет выполнять следующий этап сохранения.

В общем случае, каждый этап может быть разбит на некоторые под-этапы или отдельные этапы вообще могут быть пропущены. Такая структура удобна для создания иерархии классов. В каждом классе наследнике, если необходимо, перекрываю нужный метод.
...
Рейтинг: 0 / 0
01.06.2006, 19:14
    #33767216
Adic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с foxpro
Спасибо, Владимир. Это прям серьезный код, вернее для серьезнай программы )))
Я сделал по простому (методом тыка получилось) так:
на клике сохранить прописал:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
IF thisform.emptydata() = .F.
ELSE 
LOCAL m.podraz, ...
затем присваивание элементов,
далее идут разные SELECT 
с проверкой на существование данной записи 
...
ENDIF
обнудение всех текст- и комбобоксов
ENDIF

я, в принципе, это у вас и спрашивал )))
но ваш пример тоже пригодиться!

С уважением, Михаил.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Помогите с foxpro / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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