1

Тема: AHK: Передача строки A_LoopFileName в Max()

Приветствую всех.
Суть в следующем: в заданной папке есть некоторое количество файлов типа Item 01.png, Item 02.png и т.д. Необходимо получить максимальное значение у имеющихся файлов с целью создания нового, но с номером на единицу больше. Попытался получить максимальное значение вот так:

Loop, Files, Item *, R
BegStr = %BegStr%%A_LoopFileName%,
StringTrimRight, MidStr, BegStr, 1
EndStr := StrReplace(MidStr, ".png")
Info := Max(EndStr)
MsgBox, %Info%
return

Однако, как задумано оно не работает. Вся проблема, в целом сводится к передаче строки, полученной с помощью A_LoopFileName в функцию Max(). И хотя она, в результате всего проделанного с ней, должна выглядеть понятно для Max(), у него с ней что-то не так.
И да, есть подозрение, что способ, которым я решил воспользоваться вообще далек от оптимального и можно это все сделать как-то проще.

2

Re: AHK: Передача строки A_LoopFileName в Max()


newFilePattern := "Item {:02}.png"
Loop, Files, folder\Item*, R
	lastItem := A_LoopFileName
lastNumber := RegExReplace(lastItem, "Item 0+?(\d+)\.png", "$1")
MsgBox % Format("Последний файл - '{}'`nЕго нумератор - '{}'`nНовое имя файла - '{}'"
										, lastItem
										, lastNumber
										, Format(newFilePattern, lastNumber + 1))

3

Re: AHK: Передача строки A_LoopFileName в Max()

Хотя, если исследуются и подкаталоги и нужно среди всех найти максимальный номер, то, так:


maxNumber := 0, newFilePattern := "Item {:02}.png"
Loop, Files, folder\Item*, R
	maxNumber := maxNumber < (num := RegExReplace(A_LoopFileName, "Item 0+?(\d+)\.png", "$1"))
							? num : maxNumber

MsgBox % Format("Максимальный нумератор - '{}'`nНовое имя файла - '{}'"
										, maxNumber
										, Format(newFilePattern, maxNumber + 1))

4 (изменено: AndrasD, 2019-02-13 19:29:19)

Re: AHK: Передача строки A_LoopFileName в Max()

Спасибо! Механизм понятен, хотя есть пара вопросов.
1. Почему использована конструкция "Item 0+?(\d+)\.png", а не просто "Item *(\d+).png"?
2. Почему таки, вариант, приведенный мною в шапке не сработал? Max() не умеет пользоваться переменными?

Ах да, ещё один вопрос. Если использовать просто A_LoopFileName, он всегда будет возвращать последнее имя, то есть, с максимальным номером?

5

Re: AHK: Передача строки A_LoopFileName в Max()

AndrasD пишет:

1. Почему использована конструкция "Item 0+?(\d+)\.png", а не просто "Item *(\d+).png"?

Затрудняюсь ответить. Можно и так - ".*(\d+).*". Наверно, нагляднее. Первое, что пришло в голову. Почему нет?

AndrasD пишет:

2. Почему таки, вариант, приведенный мною в шапке не сработал? Max() не умеет пользоваться переменными?

Честно говоря, впервые вижу эту функцию, но судя по её описанию, в качестве параметров она принимает только числовые значения, возвращая большее из них, при этом, вернёт пустую строку, если хотя бы одно из переданных значений не является числом. Мне кажется нагляднее и проще для этого, использовать тернарные операции, чем вызывать целую функцию.

AndrasD пишет:

Если использовать просто A_LoopFileName, он всегда будет возвращать последнее имя, то есть, с максимальным номером?

В такой структуре файлов:


 - rootFolder
	* Item 01
	* Item 02
	* Item 03
	* Item 11
	* Item 22
	* Item 33
	 - innerFolder_1
		* Item 03
		* Item 04
		* Item 55
	 - innerFolder_2
		* Item 01
		* Item 02
		* Item 07
	 - innerFolder_3
		* Item 03
		* Item 04
		* Item 05

Последний вариант должен вернуть 55, в то время как последним файлом должен оказаться "Item 05".

6

Re: AHK: Передача строки A_LoopFileName в Max()

Я пробовал Max(Item 01, Item 02) и он все делал корректно, значения, не являющиеся числом просто игнорируя. Или заменяя на пустое, что в данном случае не важно. Однако, когда точно такое же содержимое загружалось через переменную, ничего не получалось.
Но, как выяснилось, можно было получить максимальное значение и без сравнения всех файлов.
В любом случае, спасибо за помощь.

7

Re: AHK: Передача строки A_LoopFileName в Max()

Совершенно верно, границы строки принято обозначать двойными кавычками("Item 01"), иначе, литералы воспринимаются интерпретатором как имена переменных. В вашем случае:

Max(Item 01, Item 02)

Внутри круглых скобок подразумевается две операции конкатенации строки, состоящей из цифр, впереди-идущий ноль которой будет отброшен при математических операциях над ней:

MsgBox % 01 + 0

И переменной "Item", которая не была ранее объявлена, а потому, содержит "пустое значение", что в результате аналогично тому, если бы эта операция не производилась. Эквивалент:

x := Item 01
y := Item 02
MsgBox % x "`n" y
MsgBox % x > y ? "Икс(" . x + 0 . "), больше игрек" : "Игрек(" . y + 0 . "), больше икс"

Вам будет полезно почитать о переменных и выражениях. Перевод старый, но актуальный.

8

Re: AHK: Передача строки A_LoopFileName в Max()

Спасибо, надо будет почитать повнимательнее.