Исходник Гайд AUTOHOTKEY | Loop, * | Циклы

BASS_DEVSOFTWARE

Известный 🇺🇦
Автор темы
Друг
263
570
Данная статья нужна лишь для краткого и быстрого ознакомления с материалом из справки (Loop)!
Я не отрицаю факт того, что многое из ниже представленного можно найти в справке, я лишь хотел попытаться донести некоторую информацию более доступно для рядовых чайников пользователей.



autohotkey.png



image.png

Начнём с базового - Loop, count

image.png


Малость теории: циклом может называться любая многократно исполняемая последовательность инструкций, организованная любым способом.
Закончили теорию.


Цикл заключаем в { и } скобки, выглядит это дело примерно так:​

AutoHotKey:
Loop, количество повторений
{
;Code
}

Между { и } должен находиться исполняемый циклом код, например:​

AutoHotKey:
Loop, 10
{
var += 1
msgbox %var%
;Каждый последующий msgbox будет показывать число на единицу больше.
}
; Либо, как и условия, loop можно записать без { }, с одной строкой под самим Loop.

  Loop, 10
  msgbox %a_index%

Количество повторений (count) можно указать в виде переменной:​

AutoHotKey:
count = 10
Loop, %count%
{
var += 1
msgbox %var%
;Каждый последующий msgbox будет показывать число на единицу больше.
}

Так же, мы можем опустить count и цикл будет работать до момента, пока break не встанет на пути исполнения.​

AutoHotKey:
Loop
{
var += 1
msgbox %var%
;Каждый последующий msgbox будет показывать число на единицу больше.
}

image.png

Переходим к построчному чтению файла - Loop, Read

image.png



Loop, Read лучший аналог FileReadLine, так как первый вариант один раз открывает файл и держит его открытым во время цикла, в отличии от второго, который открывает, читает и закрывает.

Строка выглядит таким образом:

AutoHotKey:
Loop, Read, Читаемый файл [, Дополнительно открытый файл]
; Дополнительный файл так же открыт на протяжении всего цикла
;Указывать доп.файл - не обязательно.

Читаемый файл так же можно указать в виде переменной.

Во время работы цикла, читаемые строки содержатся в переменной цикла %A_LoopField%.

AutoHotKey:
Loop, read, D:\file.txt
{
  msgbox, Содержание строки №%A_Index%: %A_LoopField%
;A_Index - переменная, что хранит в себе номер обрабатываемого цикла.
}

Дополнительный файл может очень пригодится. Например при переносе лишь необходимых нам строк из Читаемого файла в Дополнительный.
A_Index находится во всех типах цикла.

AutoHotKey:
Loop, read, D:\file.txt

{

     IfInString, A_LoopReadLine, FindingText, FileAppend, %A_LoopReadLine%`n

}

Если в тексте строки найдено "FindingText", мы переписываем всю строчку в Дополнительный файл новой строкой (`n - начинает новую строку).


image.png

Чтение под строк через Loop, Parse

image.png



Loop, Parse позволяет читать содержимое каждой строки через разделители и убирать неугодные нам слова/символы, если нам это нужно.

Рассмотрим простой пример:

AutoHotKey:
Colors = красный,зеленый,синий
Loop, parse, Colors, `,
{
    MsgBox, Цвет номер %A_Index%: %A_LoopField%.
}

A_LoopField содержит содержимое читаемой строки, до разделителя.
В нашем случае, разделитель - запятая.

AutoHotKey:
Text= ОдинДва, 123123123, карлукларыукр,ал каралы.
Loop, parse, Text, `,
{
    MsgBox, Номер %A_Index%: %A_LoopField%.
}

Из примера выше, msgbox подряд будет показывать:
  • ОдинДва​
  • 123123123​
  • карлукларыукр​
  • ал каралы​
Между "карлукларыукр" и "ал каралы" стоит запятая, которая разделяет наше предложение на разные по счёту строки.

AutoHotKey:
Loop, Parse, InputVar, НАШ РАЗДЕЛИТЕЛЬ

Разделитель может быть не только символом.​

AutoHotKey:
Loop, Parse, InputVar, Наш разделитель, УДАЛЯЕМЫЕ СИМВОЛЫ

Удаляемые символы ещё одна приятность. Среди читаемых под строк мы можем удалять указанные нами символы, но только с начала или конца.​

AutoHotKey:
Loop, Parse, InputVar, Наш разделитель, @
;Убираем @ из начала и конца под строки

image.png

Loop, FilePattern - просмотр файлов и папок по директории.

image.png

AutoHotKey:
Loop, Искомые файлы, путь. [, Просматривать ли папки, Рекурсия в под папки]


Название файла цикла помещено в переменную A_LoopFileName

Loop, FilePattern позволяет вычислять размер файла, дату изменения, дату последнего запуска и т.д. Больше в таблице ниже:
A_LoopFileName​
Имя текущего файла или папки (без пути).​
A_LoopFileExt​
Расширение файла (например, TXT, DOC, или EXE). Точка (.) не включается.​
A_LoopFileFullPath​
Полный путь и имя текущего файла/папки. Однако, если FilePattern содержит не полный, а относительный путь, то путь здесь также будет относительным. Вдобавок, все короткие (8.3) имена папок в FilePattern останутся короткими (длинный вариант см. в следующем пункте).​
A_LoopFileLongPath​
Отличается от A_LoopFileFullPath тем, что: 1) всегда содержит полный/абсолютный путь файла, даже если FilePattern содержит относительный путь; 2) все короткие (8.3) имена папок в FilePattern конвертируются в длинные; 3) буквы в FilePattern переводятся в верхний либо нижний регистр, чтобы имена приняли тот вид, в котором они хранятся в файловой системе. Это полезно для приведения имён файлов - таких как те, что передаются в скрипт как параметры командной строки - точно к тому виду, в каком они показываются в Проводнике.​
A_LoopFileShortPath​
Короткое имя в формате 8.3 для текущего файла/папки. Например, C:\MYDOCU~1\ADDRES~1.txt. Однако, если FilePattern содержит не абсолютный, а относительный путь, то путь здесь тоже будет относительным.​
A_LoopFileShortName​
Короткое имя файла в формате 8.3. Если файл не имеет такого имени (в силу того, что длинное имя короче, чем 8.3 или, возможно, потому, что создание коротких имён отключено в файловой системе NTFS), взамен будет возвращено значение для A_LoopFileName.​
A_LoopFileDir​
Полный путь каталога, в котором находится A_LoopFileName. Однако, если FilePattern содержит не абсолютный, а относительный путь, то и здесь путь также будет относительным. Путь к корневому каталогу не будет иметь обратной косой черты на конце. Например: С:​
A_LoopFileTimeModified​
Время последнего изменения файла. Формат YYYYMMDDHH24MISS. (Прим. переводчика: см. расшифровку этого формата в описании FileGetTime).​
A_LoopFileTimeCreated​
Время создания файла. Формат YYYYMMDDHH24MISS​
A_LoopFileTimeAccessed​
Время последнего доступа к файлу. Формат YYYYMMDDHH24MISS.​
A_LoopFileAttrib​
Атрибуты текущего файла. (Прим. переводчика: подробнее см. в описании FileGetAttrib).​
A_LoopFileSize​
Размер текущего файла в байтах. Файлы больше 4 Гб также поддерживаются.​
A_LoopFileSizeKB​
Размер текущего файла в килобайтах, округлённый до ближайшего снизу целого числа.​
A_LoopFileSizeMB​
Размер текущего файла в мегабайтах, округлённый до ближайшего снизу целого числа.​

Искомые файлы (FilePattern) - путь, в котором скрипт будет просматривать файлы.

Просматривать ли папки (IncludeFolders) - засчитывать ли папку за отдельный файл, который скрипт посчитает нужным просмотреть.

Рекурсия в под папки (Recurse) - просматривать ли содержимое находящихся по пути FilePattern папок.

===

Визуально представим нашу папку, в ней будут следующие файлы:

text.txt​
mine.txt​
Folder​
h.psd​
file.exe​
text.ini​
Folder2​
asd.ini
ios.iso​
uus.exe​

FilePattern можно указать как ПУТЬ\*.ФОРМАТ
* - любое название
Формат можно указать через .* , чтобы цикл просматривал все файлы, всех форматов.​

AutoHotKey:
Loop, D:\*.txt, папки, рекурсия

Наш цикл определил:​

text.txt​
mine.txt​

=====

IncludeFolders
указываем как 1, 2 или 0.
1 - Возвращаются все файлы и папки.
2 - Возвращаются только папки.
0 - Возвращаются только файлы. (по умолчанию)​

AutoHotKey:
Loop, D:\*.txt, 1, рекурсия

Наш цикл определил:​

text.txt​
mine.txt​
Folder​
Folder2​

=====

Recurse так же указываем цифрой - 0 или 1.
0 - Рекурсия в под папки не производится.
1 - Рекурсия в под папки производится и возвращаются все папки и файлы в них, совпадающие с FilePattern.
Рекурсия производится во все под папки, не только в те, чьи имена совпадают с FilePattern.​

AutoHotKey:
Loop, D:\*.txt, 1, 1

Наш цикл определил:​

Folder​
Folder2​
text.txt​
mine.txt​
asd.ini​
ios.iso​
uus.exe​


image.png

Цикл с условием, я говорю о While-Loop

image.png



В цикле можно указать любое условие или функцию.​

AutoHotKey:
while expression

Пример из справки:​

AutoHotKey:
while GetKeyState("LButton")
;Если нажата ЛКМ - выполняем действие внутри цикла.

Если условие верное - цикл выполняется по кругу, однако когда условие станет неверным - цикл завершит свою работу.

Простой пример:​

AutoHotKey:
asd = 1
while asd > dsa
;Если asd > dsa - показывается msgbox 1
{
    MsgBox 1
}
MsgBox end

Numpad0::
dsa = 2
;Условие в while станет неверным и цикл завершится, показав msgbox end


image.png

For Key, Value in Expression

image.png


For loop позволяет нам обрабатывать условие в цикле с несколькими переменными.
Содержание переменных остаётся неизменными, во время работы цикла.​

AutoHotKey:
For 1key, 2 in Условие

Для примера:

AutoHotKey:
numbers := Object("one", "1", "two", "2", "three", "3")
for k, v in numbers
MsgBox %k% %v% ; В первом msgbox K содержит "one", а V содержит "1"

Пример от пользователя @arsh12344

AutoHotKey:
object := {1:"abc", "abc":2, "name":"tutor", 2:"Any object"}
object.anyValue := 100500
object.trallala := 23232
for key, value in object ;Цикл проходит ПО ВСЕМ объектам.
  msgbox % key " - " value

Перед вторым использованием цикла мы можем очистить ключи:​

AutoHotKey:
Object.Remove(first, last)

image.png

Цикл для просмотра содержимого реестра - Loop, RootKey

image.png


RootKey - корень раздела, в который мы идём.
Key - уже имя раздела, это и будет читаться.

IncludeSubkeys - схоже с IncludeFolders, указываем - читать ли под разделы (Key).​
  • 0 - Подразделы указанного раздела не читаются (По умолчанию.)​
  • 1 - Читаются все параметры и подразделы.​
  • 2 - Читаются только подразделы.​
Recurse - будет ли происходить рекурсия в подразделы.​
  • 0 - Рекурсия в подразделы не выполняется (По умолчанию.)​
  • 1 - Извлекается из подразделов все параметры и под разделы.​
AutoHotKey:
Loop, Корень [, Раздел, Просматривать под раздел отдельно, Рекурсия в под разделы]


Ниже представлю таблицу с переменными, которые существуют в цикле:
A_LoopRegName​
Имя текущего считанного элемента, которое может быть либо именем параметра, либо именем подраздела. Параметры, которые в редакторе реестра Windows (regedit.exe) показываются как "(По умолчанию)", читаются, если им присвоено какое-то значение, но A_LoopRegName будет для них пустой.​
A_LoopRegType​
Тип текущего считанного элемента. Может быть одним из следующих слов: KEY (раздел), REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ, REG_DWORD, REG_QWORD, REG_BINARY, REG_LINK, REG_RESOURCE_LIST, REG_FULL_RESOURCE_DESCRIPTOR, REG_RESOURCE_REQUIREMENTS_LIST, REG_DWORD_BIG_ENDIAN (вероятно, редкость на большинстве компьютеров с Windows). Если тип неизвестен, переменная будет пустой.​
A_LoopRegKey​
Имя корневого раздела, куда осуществляется доступ (HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT, HKEY_CURRENT_CONFIG). При доступе к удалённому реестру имя компьютера сюда не включается.​
A_LoopRegSubKey​
Имя текущего подраздела. Совпадает со значением параметра Key, если в параметре Recurse не было задано рекурсивное чтение подразделов. В последнем случае в переменной будет полный путь к считанному элементу, не включающий имя корневого раздела. Например: Software\SomeApplication\My SubKey​
A_LoopRegTimeModified​
Время последнего изменения текущего подраздела или любого из его параметров. Формат: YYYYMMDDHH24MISS. Эта переменная пуста, если текущий считанный элемент не является разделом (т.е. A_LoopRegType не равна KEY) или если операционная система - Win9x (т.к. Win9x не отслеживает эту информацию).​

Внутри цикла мы получаем возможность использовать следующие команды:
RegRead, OutputVar​
Читает текущий элемент. Если это раздел, ErrorLevel будет установлен в 1, и OutputVar будет пустой.​
RegWrite​
Пишет в текущий элемент. Если значение для Value не задано, в текущий параметр реестра будет записан 0 или пустая строка, в зависимости от типа параметра. Если текущий элемент - раздел, ErrorLevel устанавливается в 1 и больше ничего не делается.​
RegDelete​
Удаляет текущий элемент. Если это раздел, он удаляется вместе со всеми подразделами и параметрами внутри него.​

Реализация. Строка ниже запишет файл file.exe в автозагрузку реестра без доп.функций.​

AutoHotKey:
RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows\CurrentVersion\Run,, С:\file.exe



  • На целевой машине должна быть запущена служба "Удалённый реестр" ("Remote Registry").​
  • Доступ к удалённому реестру может не удаться, если целевой компьютер не в том же домене, что и ваш, или если локальная или удалённая учётная запись не обладает достаточными разрешениями (впрочем, смотрите ниже возможные обходные пути).​
  • В зависимости от домена, рабочей группы и/или разрешений вашей учётной записи вам может потребоваться подключение к сетевому устройству, такому как сетевой диск, перед тем как пытаться получить доступ к удалённому реестру. Осуществление такого подключения - с использованием имени и пароля удалённого пользователя, имеющего право на доступ к реестру или его редактирование - может, как побочный эффект, задействовать доступ к удалённому реестру.​
  • Если вы уже подключены к целевому компьютеру под другим именем (например, к сетевому диску как пользователь Гость), вам, возможно, придётся прервать это соединение, чтобы позволить службе удалённого реестра переподключить и перерегистрировать вас с вашим собственным именем пользователя.​
  • Для Windows Server 2003 и Windows XP Professional MSDN сообщает: "Если компьютер входит в рабочую группу и задействована политика "Force network logons using local accounts to authenticate as Guest" ("Вход в систему через сеть по локальной учётной записи разрешён только под именем Гость"), эта функция не действует. Имейте в виду, что эта политика включена по умолчанию, если компьютер входит в рабочую группу."​
  • Для Windows XP Home Edition MSDN сообщает, что "эта функция никогда не действует".​
  • Если кому-то точно известно, применимы ли последние два пункта выше к локальному компьютеру, к удалённому или к обоим, пожалуйста, свяжитесь с автором.​


image.png

Break и Continue

image.png


Break и Continue можно использовать только в цикле.
Break - завершает цикл, когда continue служит своеобразным goto, только внутри цикла.

AutoHotKey:
Continue , Label
Break , Label


Метка должна быть непосредственно В цикле или НАД ним.

Пример, который может наглядно показать суть и применение continue и break.
AutoHotKey:
  okey:
loop {
   if a_index = 5
      break
   MsgBox 1 %a_index% ; Когда a_index внешнего цикла будет = 5, мы увидим msgbox end
   loop {
      if a_index = 3
         continue okey ; переходим на внешний цикл
      MsgBox 2 %a_index% ;Msgbox 2 3 - мы никогда не увидим, так как уже после 2 2 наше условие делает переход на метку okey, благодаря условию if a_index = 3
   }
}
MsgBox end ; Сработало наше условие if a_index = 5

892e94b79b.png


На этом, пожалуй, мы закончим.
Отдельная благодарность ресурсу ahk-wiki.ru за помощь.

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


@arsh12344
Добавлен пример для For, Loop
@Belo4ka_belka
Помощь с табуляцией и For, Loop

Спасибо вам огромное!

Любые вопросы можете задавать в данной теме и просьба БЛАГОДАРИТЬ тех, кто вам поможет своим ответом.

 
Последнее редактирование:

index

Известный
125
82
Раз уж тема с циклами - где цикл прохода по элементам объекта?
AutoHotKey:
object := {1:"abc", "abc":2, "name":"tutor", 2:["Any object"]}
object.anyValue := 100500
for key, value in object
  msgbox % key " - " value
 
  • Нравится
Реакции: AnWu

AnWu

Известный
Всефорумный модератор
4,777
5,399
???
 

Вложения

  • Screenshot_2019-04-04-09-05-55.png
    Screenshot_2019-04-04-09-05-55.png
    23.9 KB · Просмотры: 480
  • Screenshot_2019-04-04-09-06-06.png
    Screenshot_2019-04-04-09-06-06.png
    29.8 KB · Просмотры: 483

Belo4ka_belka

Известный
191
7
Да, for k одно из самых основных вариантов применения циклов на практике, надо бы дописать. И если ты хочешь учить пользователей, то сначала поясни им за табуляцию и отступы в целом и сам не серчай с этим методом. А вместо continue okey лучше break использовать ("мне нужно прервать цикл и вместо того чтобы его прервать я перезапущу мой родительский цикл"). За 4 года использования я ни разу не встречал ситуаций когда continue label или break label нужно было применить и вот я увидел свой первый пример, который совсем неюзабельный)
 
Последнее редактирование:

BASS_DEVSOFTWARE

Известный 🇺🇦
Автор темы
Друг
263
570
Извращался как мог. Хотел сделать всё по центру и т.д., но с мобилами история видимо другая :mad:
Screenshot-26.png

Раз уж тема с циклами - где цикл прохода по элементам объекта?
AutoHotKey:
object := {1:"abc", "abc":2, "name":"tutor", 2:["Any object"]}
object.anyValue := 100500
for key, value in object
  msgbox % key " - " value
Запамятовал. Добавлю.
Да, for k одно из самых основных вариантов применения циклов на практике, надо бы дописать. И если ты хочешь учить пользователей, то сначала поясни им за табуляцию и отступы в целом и сам не серчай с этим методом. А вместо continue okey лучше break использовать ("мне нужно прервать цикл и вместо того чтобы его прервать я перезапущу мой родительский цикл"). За 4 года использования я ни разу не встречал ситуаций когда continue label или break label нужно было применить и вот я увидел свой первый пример, который совсем неюзабельный)

По поводу for key - добавлю.
За continue okey согласен, я просто хотел показать пример с наглядной реализацией.
О табуляции, где моя оплошность?
 
  • Нравится
Реакции: AnWu