powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / MULTISELECT и MRKBAR()
12 сообщений из 12, страница 1 из 1
MULTISELECT и MRKBAR()
    #36076591
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем добрый день!
Столкнулась с интересной ситуацией при работе с меню.


DEFINE POPUP men1 FROM 10,10 MULTI margin TITLE 'Услуги'

for ii=1 to kol_usl
define bar ii of men1 PROMPT ALLTRIM(STR(rez3(ii))) + '. ' + alltrim(rez5(ii)) + ' ' + ALLTRIM(STR(rez6(ii),6,2))
endfor
on sele popu men1 do vm1 with prompt(), bar()
acti popup men1


PROCEDURE vm1
param ks1, ks3

if mrkbar('men1',ks3)

n_labr(zz) = r_labr(ks3)
v_gr_pech(zz) = r_gr_pech(ks3)
v_vich(zz) = r_vich(ks3)
v_ne_pech(zz) = r_ne_pech(ks3)

ENDIF

set mark of bar ks3 of men1 to .t.
DEFINE BAR ks3 OF men1 PROMPT ks1 COLOR scheme 3

retu


Если определяю меню с мультивыбором (параметр MULTISELECT), то mrkbar('men1',ks3) на входе в программу vm1 на все элементы меню сразу .t., хотя set mark ещё не было.
Если убираю параметр MULTISELECT), то mrkbar('men1',ks3) - .f. и становится .t. только после set mark.

Поэтому никак не могу сделать включение-выключение пунктов меню.

Что я делаю не так?
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36076929
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Неужели никто не сталкивался с таким, может это у меня FOX глючит (7 версия)?
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077045
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здесь путаница в назначении функции mrkBar().

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

SET MARK OF BAR ... OF ... TO .T.

Однако в режиме множественного выбора (Multiselect) эта же функция проверяет уже не факт наличия/отстутствия "птички", а факт выбора соответствующего пункта меню. Ведь выбрано может быть несколько пунктов. При этом, никаких птичек слева от выбранных пунктов не ставится. Они просто подсвечиваются контрастным цветом.

Другими словами, режимы MULTISELECT и SET MARK OF - не совместимы, если предполагается использовать mrkBar(). Она будет показывать выбранный, а не помеченный пункт меню.
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077073
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как проверить, выбран ли данный пункт меню при MULTISELECT.
Это нужно, чтобы пользователь имел возможность отменить выбранный неверно пункт за один приемю
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077079
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Запуталась в терминах, надо отменить пометку пункта.
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077136
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АленаША как проверить, выбран ли данный пункт меню при MULTISELECT.
Это нужно, чтобы пользователь имел возможность отменить выбранный неверно пункт за один приемю
Так ведь в справке по команде DEPINE POPUP дан прекрасный пример использования именно MULTISELECT.

Вот код из справки по VFP7

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
CLEAR
IF NOT _DOS
   MODIFY WINDOW SCREEN FONT 'foxfont',  12 
ENDIF

ACTIVATE SCREEN
DEFINE POPUP popFruits FROM  5 , 5  MULTISELECT MARGIN          && Create multi-choice menu
DEFINE BAR  1  OF popFruits PROMPT '\<Apples'  MARK CHR( 3 )     && First item
DEFINE BAR  2  OF popFruits PROMPT '\<Bananas' MARK CHR( 4 )    && Second item
DEFINE BAR  3  OF popFruits PROMPT '\<Grapes'  MARK CHR( 5 )     && Third item
DEFINE BAR  4  OF popFruits PROMPT '\<Lemons'  MARK CHR( 6 )    && Fourth item

@  12 , 5  SAY 'Your choices:'
ON SELECTION POPUP popFruits DO yourchoice    && Choice routine
ACTIVATE POPUP popFruits 

PROCEDURE yourchoice            && Executed when choice is made
@  13 , 5  CLEAR
FOR gnCount =  1  TO CNTBAR('popFruits')      && Loop for # of items
   IF MRKBAR('popFruits', gnCount) = .T.      && Option is marked,
      ? PRMBAR('popFruits', gnCount) AT  5       && display caption
   ENDIF
NEXT

Смысл в том, что процедура YourChoice при любым выборе сканирует ВСЕ пункты меню (цикл FOR). И для каждого из них проверяет факт выбора.

В результате, внутри процедуры YourChoice получаешь полный список всех выбранных элементов меню.
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077229
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так дело в том, что если один раз выбрал, то mrkbar остается .t., а мне надо, чтобы при повторном выборе происходила отмена и пометка убиралась.
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077428
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я же уже сказал, что SET MARK и MULTISELECT - несовместимы в части использования mrkBar().

Либо выбирайте по одному пункту за раз и вручную ставите SET MARK (тогда выбор остается "навсегда")

Либо выбираете по несколько пунктов сразу, но результат выбора забывается сразу после выбора.

Впрочем, можно попробовать хранить номера пунктов для которых сделана настройка SET MARK в каком-либо отдельном глобальном массиве, вообще не обращаясь к функции mrkBar(). Т.е. функция mrkBar() будет использоваться только для фиксации множественного выбора.

Код: 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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
* Глобальный массив для хранения номеров помеченных пунктов меню
Public gaSelectedBar( 1 )

Define Popup men1 From  10 , 10  MultiSelect Margin Title 'Услуги'

For ii= 1  To kol_usl
	Define Bar ii Of men1 Prompt ;
		Alltrim(Str(rez3(ii))) + '. ' + Alltrim(rez5(ii)) + ' ' + Alltrim(Str(rez6(ii), 6 , 2 ))
Endfor

On Sele Popu men1 Do vm1 With Prompt(), Bar()
Activate Popup men1


Procedure vm1
Lparameters ks1, ks3
* Раз вообще попали сюда, то Bar-пункт с номером ks3 был выбран
* Т.е. mrkbar('men1',ks3) вернет .T.
* Проверяем, был ли он уже помечен ранее

Local lnElement
lnElement = Ascan(gaSelectedBar, ks3)
If  lnElement >  0 
	* Да. Этот пункт меню уже был помечен ранее
	* Снимаем метку
	Set Mark Of Bar ks3 Of men1 To .F.
	* Удаляем номер пункта меню из массива
	=Adel(gaSelectedBar, m.lnElement)
	* И уменьшаем размерность массива
	Dimension gaSelectedBar(Alen(gaSelectedBar)- 1 )
Else
	* Нет. Этот пункт меню ранее не был помечен
	* Устанавливаем метку
	Set Mark Of Bar ks3 Of men1 To .T.
	* Увеличиваем размерность массива
	Dimension gaSelectedBar(Alen(gaSelectedBar)+ 1 )
	* И записываем номер пункта меню в массива
	gaSelectedBar[Alen(gaSelectedBar)] = ks3
Endif

Return
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077454
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо большое, у меня как раз только что все получилось, и почти как у Вас. Значит, мыслю верно.


if zz<kol_usl
if mrkbar('men1',ks3) = .t.
IF ASCAN(rez2,VAL(SUBSTR(ks1,1,AT('.',ks1)-1))) = 0
zz=zz+1

rez2(zz) = VAL(SUBSTR(ks1,1,AT('.',ks1)-1))
rez4(zz)= SUBSTR(ks1,AT('.',ks1)+2,AT('_',ks1)-(AT('.',ks1)+2))

set mark of bar ks3 of men1 to mrkbar('men1',ks3) = .t.
DEFINE BAR ks3 OF men1 PROMPT ks1 COLOR scheme 3
ELSE

ud_ar = ASCAN(rez2,VAL(SUBSTR(ks1,1,AT('.',ks1)-1)))
set mark of bar ks3 of men1 to mrkbar('men1',ks3) = .f.
= ADEL(rez2,ud_ar)
= ADEL(rez4,ud_ar)
zz=zz - 1

endif
ENDIF


endif
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36077551
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Окончательно получилось так:

Код: 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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
PROCEDURE vm1
param ks1, ks3

if zz<kol_usl

if mrkbar('men1',ks3) = .t.

* Если не был ранее выбран, отмечаем и запоминаем номер и название пункта меню в массивы
IF ASCAN(rez2,VAL(SUBSTR(ks1, 1 ,AT('.',ks1)- 1 ))) =  0 
zz=zz+ 1 

rez2(zz) = VAL(SUBSTR(ks1, 1 ,AT('.',ks1)- 1 ))
rez4(zz)= SUBSTR(ks1,AT('.',ks1)+ 2 ,AT('_',ks1)-(AT('.',ks1)+ 2 ))
 
   set mark of  bar ks3 of men1 to  .t.

ELSE
 
* Если  был ранее выбран, отменяем отметку, удаляем соответствующие элементы массивов
  ud_ar = ASCAN(rez2,VAL(SUBSTR(ks1, 1 ,AT('.',ks1)- 1 )))
   set mark of  bar ks3 of men1 to  .f.

= ADEL(rez2,ud_ar) 
= ADEL(rez4,ud_ar) 
zz=zz -  1 

* Удаление элемента  из массива не изменяет общую размерность массива; при этом конечные 
* элементы массива перемещаются к началу массива, заменяя "места" удаленных элементов, 
* Конечные элементы в массиве принимают значения = False (.F.).
* Поэтому корректирую последние элементы массива

rez2(ALEN(rez2)) =  0 
rez4(ALEN(rez4)) = ''

endif

ENDIF

endif
retu


ВладимирМ, спасибо Вам!
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36078270
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если вы размерность массивов все-равно не меняете, то имеет смысл создать массив с размерностью, равной максимально возможному значению параметра k3. Т.е. тому, что возвращает Bar().

Тогда вместо ASCAN() надо будет просто обратится к нужному элементу массива

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
* Глобальный массив для хранения номеров помеченных пунктов меню
Public gaSelectedBar( 10 )


PROCEDURE vm1
param ks1, ks3

if gaSelectedBar[ks3] = .T.
	* Элемент уже был выбран
	gaSelectedBar[ks3] = .F.
else
	* Элемент еще не был выбран
	gaSelectedBar[ks3] = .T.
endif

Кстати, массив может быть и двумерным. Поэтому в нем же, но в других столбцах, если необходимо, можно хранить и фрагменты ks1

И еще раз напоминаю, про бессмысленность проверки

if mrkbar('men1',ks3) = .t.

Она же всегда будет выполняться при использовании MULTISELECT. Зачем делать бессмысленную работу и усложнять код?
...
Рейтинг: 0 / 0
MULTISELECT и MRKBAR()
    #36079140
АленаШ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВладимирМ, учту советы!
Конечно, код ешё почищу, а размерность массива у меня как раз совпадает с количеством пунктов меню. Уменьшать его не могу, так как вдруг они опять передумают и начнут выбирать все подряд по максимуму,
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / MULTISELECT и MRKBAR()
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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