Что нового

Зациклить Select или Switch пока все case не будут соответствовать условию

pra8edn1k

Новичок
Сообщения
4
Репутация
0
Добрый день!

В autoit я еще зеленый новичок. Прошу помощи решить для многих примитивную задачку.
Матчасть изучал. Пока не дошло решение.

Задаются параметры для переменных true или false:
Код:
$patch_1 = True
$patch_2 = True
$patch_3 = True


Выполняю к примеру Select:
Код:
Select
				Case $patch_1 = True
					;функция
					$patch_1 = False
				Case $patch_2 = True
					;функция
					$patch_2 = False
				Case $patch_3 = True
					;функция
					$patch_3 = False
			EndSelect


Надо выполнять этот Select пока все case не вернут false.
Вот что пробовал:
Код:
$i = 0
$patch_1 = True ;Может быть false
$patch_2 = True ;Может быть false
$patch_3 = True ;Может быть false

Do
			Select
				Case $patch_1 = True
					;функция
					$patch_1 = False
				Case $patch_2 = True
					;функция
					$patch_2 = False
				Case $patch_3 = True
					;функция
					$patch_3 = False
			EndSelect
			$i = $i + 1
Until $i = 3


;Пробовал еще такой вариант.
-----------------------------------------

Do
			Switch True
				Case $patch_1 = True
					;функция
					$patch_1 = False
				Case $patch_2 = True
					;функция
					$patch_2 = False
				Case $patch_3 = True
					;функция
					$patch_3 = False
			EndSwitch
Until ;Не знаю что за условие поставить.

P.S. Первый вариант конечно работает, но думаю можно сделать проще.
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Код:
Do
    ; твой select
Until Not $patch_1 And Not $patch_2 And Not $patch_3
 
Автор
P

pra8edn1k

Новичок
Сообщения
4
Репутация
0
А если это отмасштабировать. Предположим в будущем будет не 3 $patch а 200 ($patch_1-$patch[n]). Можно это как-то объединить в массив.
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
pra8edn1k сказал(а):
А если это отмасштабировать. Предположим в будущем будет не 3 $patch а 200 ($patch_1-$patch[n]). Можно это как-то объединить в массив.
Ну да, конечно можно. Даже нужно. Так и делают, через массивы.
Код:
#include <Array.au3> ; for _ArrayDisplay
Dim $patch[3] = [True, True, True]

_ArrayDisplay($patch)

For $i = 0 To UBound($patch) - 1
	Select
		Case $patch[$i] = True
			;функция ($i)
			$patch[$i] = False
	EndSelect
Next
_ArrayDisplay($patch)
 
Автор
P

pra8edn1k

Новичок
Сообщения
4
Репутация
0
Спасибо! Массив реально помог сделать код чище и надежней. Может тогда дадите совет как упростить запись внутри case (за основу взял ответ выше):

Код:
$patchCheck_1 = True ; i = 0
$patchCheck_2 = False ; i = 1
$patchCheck_3 = True ; i = 2

Dim $patch[3] = [$patchCheck_1, $patchCheck_2, $patchCheck_3]


For $i = 0 To UBound($patch) - 1
    Select
		Case $patch[$i] = True

			#comments-start
			if $i = 0 Then
				FunPatch_1()
			EndIf

			if $i = 1 Then
				FunPatch_2()    Как можно упростить данную конструкцию?
			EndIf

			if $i = 2 Then
				FunPatch_3()
			EndIf
			#comments-end

            $patch[$i] = False
    EndSelect
Next

;func FunPatch_1()
;func FunPatch_2()
;func FunPatch_3()
 

hedji

Продвинутый
Сообщения
409
Репутация
94
Избавиться от FunPatch_1(), func FunPatch_2()
Переписать FunPatch() так, чтобы принимала на вход аргумент:
Код:
  Select
        Case $patch[$i] = True
                FunPatch($i)            
            $patch[$i] = False
    EndSelect
Если покажете что именно делают FunPatch_1(), func FunPatch_2(), можно будет ответить подробнее.
 

alex33

Скриптер
Сообщения
1,457
Репутация
186
Зачем эти первые три строки? Зачем лишние переменные? Пиши сразу в массив!!!
Одну функцию сделай с параметром, с аргументом!
Код:
Func patch ( $i )
	; что там у тебя,
;установка программ?
	; сделай такойже массив и также вызывай
	; или так:
	; If $i = 1 Then ; делай это
	; If $i = 2 Then ; или это
EndFunc

Я же в первом сообщении сказал об этом.
Нет, есть еще кастыльный способ.
Есть функция под названием Execute . Можно написать так:
Код:
; если $i = 2 , то это выражение
Execute ( "patch_" & $i & "()")
; будет равносильно
patch_2()
; только в цикле переменная будет меняться.
 
Автор
P

pra8edn1k

Новичок
Сообщения
4
Репутация
0
hedji сказал(а):
Если покажете что именно делают FunPatch_1(), func FunPatch_2(), можно будет ответить подробнее.

FunPatch_1(), func FunPatch_2() - выполняют набор стандартных операций. Изменить в реестре ветку, удалить или добавить файл, запустить программу с параметром и т.д.

alex33 сказал(а):
Зачем эти первые три строки? Зачем лишние переменные? Пиши сразу в массив!!!

Там происходит проверка GUICtrlCreateTreeViewItem, пока не придумал как это сразу записать в массив:

Код:
$patchCheck_1 = BitAND(GUICtrlRead($GUI_Patch_1), $GUI_CHECKED) = $GUI_CHECKED
			$patchCheck_2 = BitAND(GUICtrlRead($GUI_Patch_2), $GUI_CHECKED) = $GUI_CHECKED 
			$patchCheck_3 = BitAND(GUICtrlRead($GUI_Patch_3), $GUI_CHECKED) = $GUI_CHECKED


alex33 сказал(а):
Нет, есть еще кастыльный способ.
Есть функция под названием Execute . Можно написать так:
Код:
; если $i = 2 , то это выражение
[autoit]Execute ( "patch_" & $i & "()")
; будет равносильно
patch_2()
; только в цикле переменная будет меняться.

А вот этот костыльный способ, оказался просто идеальным. Всю логику уместил в 2-е строки. Как раз то что искал и даже лучше. Добился полного функционала без "раздувания" кода.

Код:
$patchCheck_1 = BitAND(GUICtrlRead($GUI_Patch_0), $GUI_CHECKED) = $GUI_CHECKED ;$i = 0
$patchCheck_2 = BitAND(GUICtrlRead($GUI_Patch_1), $GUI_CHECKED) = $GUI_CHECKED ;$i = 1
$patchCheck_3 = BitAND(GUICtrlRead($GUI_Patch_2), $GUI_CHECKED) = $GUI_CHECKED ;$i = 2

Dim $patch[3] = [$patchCheck_1, $patchCheck_2, $patchCheck_3]

			For $i = 0 To UBound($patch) - 1
    Select
		Case $patch[$i] = True

			Execute ( "FunPatch_" & $i & "()")
			GUICtrlSetState (Execute ( "$GUI_Patch_" & $i), $GUI_UNCHECKED) ;снимает галку с уже установленного патча.

            $patch[$i] = False
	EndSelect
Next

;Не хотелось объединять функции в одну. Мне так проще ориентироваться в коде + менять логику 1 "маленькой" удобней чем 1 "огромной".
;func FunPatch_0()
;func FunPatch_1()
;func FunPatch_2()
 
Верх