Вобщем ситуация:
1. Есть поля типа Edit, допустим их три (3), в них нужно вводить только integer или float. И есть Button с включённым Default.
2. Если первое поле пустое, то при нажатии Enter фокус просто остается в этом поле.
3. Если в первом поле буквы, то при нажатии Enter выводится MsgBox, и фокус остаётся в этом поле.
4. Если в первом поле integer или float, то при нажатии Enter фокус передаётся на второе поле.
Реализация (частичная, ибо «не шмогла» я в каскадные проверки):
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
uiCtrlHwnd := [hPL, hPF, hPD]
Return
Calc:
cRunVars := [0, 0, 0]
For idx, tCtrlHwnd in uiCtrlHwnd
{
GuiControlGet, tRunVar,, %tCtrlHwnd%
tRunVar := StrReplace(tRunVar,",",".")
If tRunVar Is not Number
If tRunVar Is Alpha
{
MsgBox, 0x2030, Ошибка!, "Недопустимое значение"
IfMsgBox, OK
ControlFocus,, ahk_id %tCtrlHwnd%
Return
}
Else
{
ControlFocus,, ahk_id %tCtrlHwnd%
Return
}
cRunVars[idx] := Abs(tRunVar)
}
... код непосредственно математики ...
Return
Всё работает почти как нужно, но на пустое поле выпадает MsgBox, как и на буквы в поле...
Я уже всю голову сломал переставляя местами проверки на Number и Alpha, и комбинируя их с отрицанием Not. Помогите сделать правильно, а то реально уже мозх кипит
Не получается правильно построить проверку значений Topic is solved
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Не получается правильно построить проверку значений
Код надо оформлять тэгом.
Code: Select all
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
Gui, Show
uiCtrlHwnd := [hPL, hPF, hPD], cRunVars := []
Return
Calc:
For idx, tCtrlHwnd in uiCtrlHwnd
{
GuiControlGet, tRunVar, , %tCtrlHwnd%
tRunVar := StrReplace(tRunVar,",","."), b := 0
If tRunVar =
Break
If !(b := IsIntegerOrFloat(tRunVar))
{
MsgBox, 0x2030, Ошибка!, "Недопустимое значение"
ControlSend, , {LCtrl Down}{A}{LCtrl Up}, ahk_id %tCtrlHwnd%
Break
}
cRunVars[idx] := tRunVar
}
If b && idx < uiCtrlHwnd.Count()
tCtrlHwnd := uiCtrlHwnd[++idx]
ControlFocus, , ahk_id %tCtrlHwnd%
If b
MsgBox % "Сумма: " cRunVars[1] + cRunVars[2] + cRunVars[3]
Return
IsIntegerOrFloat(var) {
if var is integer
Return 1
if var is float
Return 1
}
Re: Не получается правильно построить проверку значений
Вобщем я так и подумал, что без наворота костылей тут не обойтись... Но Ваш пример оказался не бесполезен, и навёл меня на мысль. Вот мой вариант, который в принципе меня полностью устраивает:
1. Break в теле цикла недопустим. Он прервёт цикл, и отправит незаполненный полностью массив cRunVars[] в расчёты. С соответствующими последствиями. Вот почему в теле цикла используется Return: он возвращает управление в основной тред до тех пор, пока массив не заполнится правильными значениями.
2. Входящие значения допустимы только целые и/или дробные положительные. Ноль недопустим. Отрицательные значения недопустимы. Вот почему функция Abs важна в строке cRunVars[idx] := Abs(tRunVar).
3. Вводить в код функцию IsIntegerOrFloat(var) нет никакой необходимости. Сдвоенную проверку на Integer и Float заменяет одна проверка на Number. Это чёрным по белому в документации.
А в целом спасибо за участие! Оно всё же помогло, хоть и отчасти.
Code: Select all
For idx, tCtrlHwnd in uiCtrlHwnd
{
GuiControlGet, tRunVar,, %tCtrlHwnd%
tRunVar := StrReplace(tRunVar,",",".")
If (tRunVar = "") or (tRunVar = 0)
{
ControlFocus,, ahk_id %tCtrlHwnd%
ControlSend,, {LCtrl Down}{A}{LCtrl Up}, ahk_id %tCtrlHwnd%
Return
}
Else If tRunVar Is not Number
{
MsgBox, 0x2030, Ошибка!, % " Недопустимое значение: " . uiCtrlNames[idx]
IfMsgBox, OK
{
ControlFocus,, ahk_id %tCtrlHwnd%
ControlSend,, {LCtrl Down}{A}{LCtrl Up}, ahk_id %tCtrlHwnd%
}
Return
} Else cRunVars[idx] := Abs(tRunVar)
}
2. Входящие значения допустимы только целые и/или дробные положительные. Ноль недопустим. Отрицательные значения недопустимы. Вот почему функция Abs важна в строке cRunVars[idx] := Abs(tRunVar).
3. Вводить в код функцию IsIntegerOrFloat(var) нет никакой необходимости. Сдвоенную проверку на Integer и Float заменяет одна проверка на Number. Это чёрным по белому в документации.
А в целом спасибо за участие! Оно всё же помогло, хоть и отчасти.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Не получается правильно построить проверку значений
Не а, в моём коде вычисляется только когда весь массив заполнен.Break в теле цикла недопустим. Он прервёт цикл, и отправит незаполненный полностью массив cRunVars[] в расчёты.
Это удобнее делать в функции, там же например проверить отрицательное, и тоже вывести MsgBox.Вводить в код функцию IsIntegerOrFloat(var) нет никакой необходимости.
Получается что отрицательное остаётся в форме, а в массив уходит положительное.
Хотя, всем этим условиям должно соответствовать только (tRunVar + 0 > 0).
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Не получается правильно построить проверку значений
Ну и в вашем случае некорректно приводить кусок кода, против моего полного, и рассказывать про "отправку в расчёты".
Без IsIntegerOrFloat.
Или с одним Break:
Без IsIntegerOrFloat.
Code: Select all
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
Gui, Show
uiCtrlHwnd := [hPL, hPF, hPD], cRunVars := []
Return
Calc:
For idx, tCtrlHwnd in uiCtrlHwnd
{
GuiControlGet, tRunVar, , %tCtrlHwnd%
If (1, b := 0) && (tRunVar := StrReplace(tRunVar,",",".")) = ""
Break
If !(b := (tRunVar + 0 > 0))
{
MsgBox, 0x2030, Ошибка!, "Недопустимое значение"
ControlSend, , {LCtrl Down}{A}{LCtrl Up}, ahk_id %tCtrlHwnd%
Break
}
cRunVars[idx] := tRunVar
}
If b && idx < uiCtrlHwnd.Count()
tCtrlHwnd := uiCtrlHwnd[++idx]
ControlFocus, , ahk_id %tCtrlHwnd%
If b
MsgBox % "Сумма: " cRunVars[1] + cRunVars[2] + cRunVars[3]
Return
Code: Select all
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
Gui, Show
uiCtrlHwnd := [hPL, hPF, hPD], cRunVars := []
Return
Calc:
For idx, tCtrlHwnd in uiCtrlHwnd {
GuiControlGet, tRunVar, , %tCtrlHwnd%
If !b := (tRunVar := StrReplace(tRunVar,",",".")) + 0 > 0
Break
cRunVars[idx] := tRunVar
}
If b && idx < uiCtrlHwnd.Count()
tCtrlHwnd := uiCtrlHwnd[++idx]
ControlFocus, , ahk_id %tCtrlHwnd%
If (!b && tRunVar != "") {
MsgBox, 0x2030, Ошибка!,% "В поле: " idx ", недопустимое значение: " tRunVar
ControlSend, , {LCtrl Down}{A}{LCtrl Up}, ahk_id %tCtrlHwnd%
}
If b
MsgBox % "Сумма: " cRunVars[1] + cRunVars[2] + cRunVars[3]
Return
Re: Не получается правильно построить проверку значений
Можете пояснить механику работы выражения tRunVar + 0 > 0 ? Я не могу понять для чего нужен именно + 0 перед оператором сравнения. Спасибо.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Не получается правильно построить проверку значений
Если в переменной буквы, они считаются как больше нуля, математическая операция вернёт пустую строку, пустота уже не больше нуля.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Не получается правильно построить проверку значений
В последнем коде осталась лишняя часть.
Code: Select all
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
Gui, Show
uiCtrlHwnd := [hPL, hPF, hPD], cRunVars := []
Return
Calc:
For idx, Hwnd in uiCtrlHwnd {
GuiControlGet, str, , %Hwnd%
If !valid := (str := StrReplace(str,",",".")) + 0 > 0
Break
cRunVars[idx] := str
}
ControlFocus, , ahk_id %Hwnd%
If (!valid && str != "") {
MsgBox, 0x2030, Ошибка!,% "В поле: " idx ", недопустимое значение: " str
ControlSend, , {LCtrl Down}{A}{LCtrl Up}, ahk_id %Hwnd%
}
Else If valid
MsgBox % "Сумма: " cRunVars[1] + cRunVars[2] + cRunVars[3]
Return
Re: Не получается правильно построить проверку значений
Вы всё же продолжаете постить неправильный код. Поясню последний раз. Задача у цикла For лишь одна - заполнить массив cRunVars[] правильными значениями, которые вводятся руками из формы GUI. До тех пор, пока это не сделано, код под Calc: дальше цикла For не исполняется. Потому что за циклом, до самого конца программы, идёт множество математических формул, использующих данные из cRunVars[], в том числе формирование ещё нескольких массивов на основе расчётов.
Я намеренно не привожу весь код, потому что не хочу. Он очень большой, входящих в cRunVars значений больше, чем 3. Все эти «пляски» с циклом только ради удобства пользования, потому что хочу предупредить процесс внесения данных в форму не только линейно, по порядку сверху-вниз, а вообще в произвольном порядке. И пока что мой вариант меня полностью устраивает: малой кровью хоть какой то порядок в царстве хаоса
Вот окончательный вариант кода:
На этом, пожалуй всё. Код работает как мне нужно. Благодарю за помощь!
ЗЫ. И да, у меня Break вместо Return в теле цикла таки прерывает его, и исполняется код, который следует за телом цикла. А нужно просто вернуться к ожиданию ввода значений в форму.
Я намеренно не привожу весь код, потому что не хочу. Он очень большой, входящих в cRunVars значений больше, чем 3. Все эти «пляски» с циклом только ради удобства пользования, потому что хочу предупредить процесс внесения данных в форму не только линейно, по порядку сверху-вниз, а вообще в произвольном порядке. И пока что мой вариант меня полностью устраивает: малой кровью хоть какой то порядок в царстве хаоса
Вот окончательный вариант кода:
Code: Select all
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
Gui, Show
uiCtrlHwnd := [hPL, hPF, hPD], uiCtrlNames := ["Длина", "Частота", "Диаметр"], cRunVars := []
Return
Calc:
For idx, tCtrlHwnd in uiCtrlHwnd
{
GuiControlGet, tRunVar,, %tCtrlHwnd%
If (tRunVar := StrReplace(tRunVar,",",".")) = ""
{
ControlFocus,, ahk_id %tCtrlHwnd%
Return
}
Else If !(tRunVar + 0 > 0)
{
MsgBox, 0x2030, Ошибка!, % " Недопустимое значение: " . uiCtrlNames[idx]
IfMsgBox, OK
{
ControlFocus,, ahk_id %tCtrlHwnd%
ControlSend,, {LCtrl Down}{A}{LCtrl Up}, ahk_id %tCtrlHwnd%
}
Return
} Else cRunVars[idx] := tRunVar
}
... математика ...
... вывод результатов ...
Return
Esc::
GuiClose:
ExitApp
ЗЫ. И да, у меня Break вместо Return в теле цикла таки прерывает его, и исполняется код, который следует за телом цикла. А нужно просто вернуться к ожиданию ввода значений в форму.
-
- Posts: 137
- Joined: 01 Jul 2017, 03:04
Re: Не получается правильно построить проверку значений
Мда, а вы всё же сказочный ... экземпляр.
Тут знаете ли помощь, а не стол заказов, и уж тем более как возможно постить неправильный код, на фоне:
Хотите правильно выстроить проверку условий, в итоге все у вас дураки, и в результате Return и ControlFocus дублирован, непонятно зачем нужный IfMsgBox. То есть по корявому переписываете мой код, и называете его неправильным, всё в лучших традициях самого умного и красивого. Вы вообще мой код запускали, или опытным взглядом сразу секёте что всё не так.
Вас слово "Break" вводит в ступор? Какая разница как выходить из цикла, если из него всё равно выходить.
Если после цикла выполнится пара строк и будет возврат, это у вас в голове не укладывается?
Если не можете заключить в блок MsgBox, может вам так понятнее.
Тут знаете ли помощь, а не стол заказов, и уж тем более как возможно постить неправильный код, на фоне:
Вы если вопрос задаёте, потрудитесь сначала вникнуть в ответ.не привожу весь код, потому что не хочу.
Хотите правильно выстроить проверку условий, в итоге все у вас дураки, и в результате Return и ControlFocus дублирован, непонятно зачем нужный IfMsgBox. То есть по корявому переписываете мой код, и называете его неправильным, всё в лучших традициях самого умного и красивого. Вы вообще мой код запускали, или опытным взглядом сразу секёте что всё не так.
Я вам уже второй раз объясняю, у меня не выполняются вычисления пока правильно не заполнены все поля.ЗЫ. И да, у меня Break вместо Return в теле цикла таки прерывает его, и исполняется код, который следует за телом цикла. А нужно просто вернуться к ожиданию ввода значений в форму.
Вас слово "Break" вводит в ступор? Какая разница как выходить из цикла, если из него всё равно выходить.
Если после цикла выполнится пара строк и будет возврат, это у вас в голове не укладывается?
Если не можете заключить в блок MsgBox, может вам так понятнее.
Code: Select all
#NoEnv
Gui, Add, Edit, vPL Limit10 HwndhPL
Gui, Add, Edit, vPF Limit10 HwndhPF
Gui, Add, Edit, vPD Limit10 HwndhPD
Gui, Add, Button, Default gCalc, Расчёт!
Gui, Show
uiCtrlHwnd := [hPL, hPF, hPD], cRunVars := []
Return
Calc:
For idx, Hwnd in uiCtrlHwnd {
GuiControlGet, str, , %Hwnd%
If !valid := (str := StrReplace(str,",",".")) + 0 > 0
Break
cRunVars[idx] := str
}
ControlFocus, , ahk_id %Hwnd%
If (!valid && str != "") {
MsgBox, 0x2030, Ошибка!,% "В поле: " idx ", недопустимое значение: " str
ControlSend, , {LCtrl Down}{A}{LCtrl Up}, ahk_id %Hwnd%
}
If !valid
Return
... математика ...
... вывод результатов ...
Return
Who is online
Users browsing this forum: No registered users and 32 guests