Информация Гайд AUTOHOTKEY | Loop, * | Циклы

Тема в разделе "AutoHotKey", создана пользователем BASS_DEVSOFTWARE, 4 апр 2019.

Метки:
  1. BASS_DEVSOFTWARE

    BASS_DEVSOFTWARE vk.com/bass_devware
    Проверенный

    Регистрация:
    29 апр 2017
    Сообщения:
    151
    Симпатии:
    114
    [​IMG]


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

    [​IMG]

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

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

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

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

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


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

    [​IMG]


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

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

    Во время работы цикла, читаемые строки содержатся в переменной цикла %A_LoopField%.
    
    Loop, read, D:\file.txt
    {
      msgbox, Содержание строки №%A_Index%: %A_LoopField%
    ;A_Index - переменная, что хранит в себе номер обрабатываемого цикла.
    }
    Дополнительный файл может очень пригодится. Например при переносе лишь необходимых нам строк из Читаемого файла в Дополнительный.
    A_Index находится во всех типах цикла.
    
    Loop, read, D:\file.txt
    
    {
    
         IfInString, A_LoopReadLine, FindingText, FileAppend, %A_LoopReadLine%`n
    
    }
    
    Если в тексте строки найдено "FindingText", мы переписываем всю строчку в Дополнительный файл новой строкой (`n - начинает новую строку).


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

    [​IMG]


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

    Рассмотрим простой пример:
    Colors = красный,зеленый,синий
    Loop, parse, Colors, `,
    {
        MsgBox, Цвет номер %A_Index%: %A_LoopField%.
    } 
    A_LoopField содержит содержимое читаемой строки, до разделителя.
    В нашем случае, разделитель - запятая.
    Text= ОдинДва, 123123123, карлукларыукр,ал каралы.
    Loop, parse, Text, `,
    {
        MsgBox, Номер %A_Index%: %A_LoopField%.
    } 
    Из примера выше, msgbox подряд будет показывать:
    • ОдинДва​
    • 123123123​
    • карлукларыукр​
    • ал каралы​
    Между "карлукларыукр" и "ал каралы" стоит запятая, которая разделяет наше предложение на разные по счёту строки.
    Loop, Parse, InputVar, НАШ РАЗДЕЛИТЕЛЬ
    Разделитель может быть не только символом.​
    Loop, Parse, InputVar, Наш разделитель, УДАЛЯЕМЫЕ СИМВОЛЫ
    Удаляемые символы ещё одна приятность. Среди читаемых под строк мы можем удалять указанные нами символы, но только с начала или конца.​
    Loop, Parse, InputVar, Наш разделитель, @
    ;Убираем @ из начала и конца под строки
    


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

    [​IMG]

    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.txtmine.txtFolderh.psdfile.exetext.iniFolder2
    asd.ini
    ios.iso
    uus.exe

    FilePattern можно указать как ПУТЬ\*.ФОРМАТ
    * - любое название
    Формат можно указать через .* , чтобы цикл просматривал все файлы, всех форматов.​
    Loop, D:\*.txt, папки, рекурсия
    Наш цикл определил:
    text.txtmine.txt
    =====

    IncludeFolders
    указываем как 1, 2 или 0.
    1 - Возвращаются все файлы и папки.
    2 - Возвращаются только папки.
    0 - Возвращаются только файлы. (по умолчанию)​
    Loop, D:\*.txt, 1, рекурсия
    Наш цикл определил:
    text.txtmine.txtFolderFolder2
    =====

    Recurse
    так же указываем цифрой - 0 или 1.
    0 - Рекурсия в под папки не производится.
    1 - Рекурсия в под папки производится и возвращаются все папки и файлы в них, совпадающие с FilePattern.
    Рекурсия производится во все под папки, не только в те, чьи имена совпадают с FilePattern.​
    Loop, D:\*.txt, 1, 1
    Наш цикл определил:
    FolderFolder2text.txtmine.txtasd.iniios.isouus.exe


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

    [​IMG]


    В цикле можно указать любое условие или функцию.​
    
    while expression
    
    Пример из справки:​
    while GetKeyState("LButton")
    ;Если нажата ЛКМ - выполняем действие внутри цикла.
    
    Если условие верное - цикл выполняется по кругу, однако когда условие станет неверным - цикл завершит свою работу.

    Простой пример:​
    asd = 1
    while asd > dsa
    ;Если asd > dsa - показывается msgbox 1
    {
        MsgBox 1
    }
    MsgBox end
    
    Numpad0::
    dsa = 2
    ;Условие в while станет неверным и цикл завершится, показав msgbox end


    [​IMG]
    For Key, Value in Expression

    [​IMG]

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

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

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

    Перед вторым использованием цикла мы можем очистить ключи:​
    Object.Remove(first, last)

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

    [​IMG]


    RootKey - корень раздела, в который мы идём.
    Key - уже имя раздела, это и будет читаться.
    IncludeSubkeys - схоже с IncludeFolders, указываем - читать ли под разделы (Key).​
    • 0 - Подразделы указанного раздела не читаются (По умолчанию.)
    • 1 - Читаются все параметры и подразделы.
    • 2 - Читаются только подразделы.
    Recurse - будет ли происходить рекурсия в подразделы.​
    • 0 - Рекурсия в подразделы не выполняется (По умолчанию.)
    • 1 - Извлекается из подразделов все параметры и под разделы.
    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 в автозагрузку реестра без доп.функций.​
    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 сообщает, что "эта функция никогда не действует".​
    • Если кому-то точно известно, применимы ли последние два пункта выше к локальному компьютеру, к удалённому или к обоим, пожалуйста, свяжитесь с автором.​

    [​IMG]
    Break и Continue

    [​IMG]

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

    Пример, который может наглядно показать суть и применение continue и break.
    
      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
    
    [​IMG]

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

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


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

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

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

    [​IMG]
     
    #1 BASS_DEVSOFTWARE, 4 апр 2019
    Последнее редактирование: 6 апр 2019
    FkeTe, Musaigen, Cucumber и 4 другим нравится это.
  2. index

    index Постоянный участник

    Регистрация:
    5 мар 2018
    Сообщения:
    75
    Симпатии:
    27
    Раз уж тема с циклами - где цикл прохода по элементам объекта?
    
    object := {1:"abc", "abc":2, "name":"tutor", 2:["Any object"]}
    object.anyValue := 100500
    for key, value in object
      msgbox % key " - " value
     
    DonHomka нравится это.
  3. DonHomka

    DonHomka Lealtà' verso la famiglia Tunes
    Друг

    Регистрация:
    8 ноя 2017
    Сообщения:
    2.541
    Симпатии:
    1.631
    ???
     

    Вложения:

  4. Belo4ka_belka

    Belo4ka_belka Интересующийся

    Регистрация:
    28 июл 2015
    Сообщения:
    120
    Симпатии:
    2
    Да, for k одно из самых основных вариантов применения циклов на практике, надо бы дописать. И если ты хочешь учить пользователей, то сначала поясни им за табуляцию и отступы в целом и сам не серчай с этим методом. А вместо continue okey лучше break использовать ("мне нужно прервать цикл и вместо того чтобы его прервать я перезапущу мой родительский цикл"). За 4 года использования я ни разу не встречал ситуаций когда continue label или break label нужно было применить и вот я увидел свой первый пример, который совсем неюзабельный)
     
    #4 Belo4ka_belka, 4 апр 2019
    Последнее редактирование: 4 апр 2019
  5. BASS_DEVSOFTWARE

    BASS_DEVSOFTWARE vk.com/bass_devware
    Проверенный

    Регистрация:
    29 апр 2017
    Сообщения:
    151
    Симпатии:
    114
    Извращался как мог. Хотел сделать всё по центру и т.д., но с мобилами история видимо другая :aggressive:
    [​IMG]

    Запамятовал. Добавлю.
    По поводу for key - добавлю.
    За continue okey согласен, я просто хотел показать пример с наглядной реализацией.
    О табуляции, где моя оплошность?
     
    DonHomka нравится это.
  6. Belo4ka_belka

    Belo4ka_belka Интересующийся

    Регистрация:
    28 июл 2015
    Сообщения:
    120
    Симпатии:
    2
    До Loop, read примеры, там строчки съехали. Ну и последний код вообще безобразно выглядит.
     
  7. BASS_DEVSOFTWARE

    BASS_DEVSOFTWARE vk.com/bass_devware
    Проверенный

    Регистрация:
    29 апр 2017
    Сообщения:
    151
    Симпатии:
    114
    @Belo4ka_belka
    @arsh12344

    Добавил For loop
    Обновил табуляцию
    Увидел ограничение в 20 картинок при создании темы -_-​