Страница 3 из 9
Добавлено: Вт окт 05, 2010 16:25
Samwatas
Rodny писал(а):
P.P.S. Поскольку с AutoIt'ом сталкиваться ещё не доводилось, ставить/компилировать несколько напряжно, если можно будет обойтись vbs, это предпочтительнее.
Напрасно, в АвтоИте есть функции предназначенные специально для работы с секциями ИНИ-файлов, как виндовые АПИ (поэтому написать такой скрипт будет легче всего).
Добавлено: Вт окт 05, 2010 16:31
Flasher
Loopback
Да Бог с тобой, какая экселевская..

Я о расположении самих окошек говорю с левой стороны. Комбинации(строка/столбец): 1x2, 2x2, 3x2, 3x3. В строку тоже ничего, но так, действительно, растянется по высоте. Если другого не дано, то, что тут поделаешь..

Окно справа пусть целиком до низа будет растянуто, если можно.
Добавлено: Вт окт 05, 2010 16:41
Batya
Flasher писал(а):Так, окей, уже лучше, а что с табуляцией делать?
Хм, ну тогда:
Код: Выделить всё
With CreateObject("TCScript.Helper")
.SetTextToClip(Replace(Replace(.GetTextFromClip, vbNewLine, "\n"), vbTab, "\t"))
End With
...
Find_String = Replace(Replace(Find_String, "\n", vbNewLine), "\t", vbTab)
...
Replace_String = Replace(Replace(Replace_String, "\n", vbNewLine), "\t", vbTab)
Добавлено: Вт окт 05, 2010 16:56
Flasher
Rodny писал(а):У меня проблема в том, что я точно знаю только название секции, т. е. я не могу здесь задать строки для поиска.
А что мешает открыть оба инишника и скопипастить целиком секции в каждое окошко и осуществить замену? Или это так часто требуется?
Добавлено: хотя нет, я тут подумал, что этот способ мало отличим от замены ручками в редакторе. Тогда, конечно, нужно искать другой способ.
Batya писал(а):Код: Выделить всё
.SetTextToClip(Replace(Replace(.GetTextFromClip, vbNewLine, "\n")), vbTab, "\t"))
Что-то на скобки ругается, не пойму почему.

Добавлено: Вт окт 05, 2010 17:43
Batya
Flasher писал(а):Что-то на скобки ругается
Исправил.
Добавлено: Вт окт 05, 2010 17:43
Rodny
Samwatas писал(а):Напрасно, в АвтоИте есть функции предназначенные специально для работы с секциями ИНИ-файлов, как виндовые АПИ (поэтому написать такой скрипт будет легче всего).
Похоже на то. То, что я поначалу принял за решение, оказалось функциями для VB(A), использующими соответствующие из WinAPI. В VBS, насколько я понял, с этим туго, народ построчно файлы перебирает.
Граждане АвтоИтовцы, если не трудно?..
Добавлено: Вт окт 05, 2010 17:55
Samwatas
Ставь конкретней задачу: с какими параметрами желаешь вызывать утиль, где хранить имя (имена) секции(й) (можно тоже в ини-файле, только в своём, а при старте утилиты подгружать), поведение утилиты при отклонениях от плана (например в первом файле не оказалось секции с данным именем, или секция пустая) и т.д.
В общем чем подробнее, тем лучше (может тебе хотелось бы видеть какие-то дополнительные опции).
Добавлено: Вт окт 05, 2010 17:58
Batya
Rodny писал(а):В VBS, насколько я понял, с этим туго, народ построчно файлы перебирает.
Если у тебя установлен TCScript.Helper, то можешь воспользоваться демо-скриптом DemoScripts\ReadWriteSection.vbs, идущим вместе со TCScript.Helper.
Добавлено: Вт окт 05, 2010 18:11
Samwatas
Без проверок на ошибки и доп. опций скрипт занимает 1 строчку:
Код: Выделить всё
IniWriteSection("C:\Temp2.ini", "section2", IniReadSection("C:\Temp1.ini", "section1"))
C:\Temp1.ini - первый инишник, из которого мы будем читать секцию.
C:\Temp2.ini - второй инишник, в который мы будем писать секцию.
section1 - имя секции, которую мы будем читать из первого файла.
section2 - имя секции, в которую мы будем писать во втором файле (может совпадать с именем первой секции, если необходимо, а может иметь и другое имя).
Если секцию во втором файле требуется предварительно удалить, то есть функция
IniDelete("filename", "section") - просто вставь её первой в скрипт (естественно, прописав нужное имя файла и секции).
П.С. Тут кто-то недавно говорил, что все скриптовые языки имеют примерно равный функционал. Ну-ну..
Добавлено: Вт окт 05, 2010 21:37
Loopback
Flasher
Ну вот, последний на сегодня вариант

Параметры интерфейса можно задать в начале скрипта, думаю там все понятно.
Код: Выделить всё
#include <GUIConstantsEx.au3>
If $CmdLine[0] < 1 Then
MsgBox (0, "", "Недостаточно параметров, должен быть 1.")
Exit
EndIf
; ================================
; Настройки отображения интерфейса
; ================================
; Число полей поиска
Global Const $gSrcCount = 3
; Высота одного поля
Global Const $gSrcHeight = 120
; ================================
Global $aList = _TCHLoadFileList($CmdLine[1])
Global $gReplaces = 0, $gMask
Global $gSrcEdit[$gSrcCount]
Global $nGUIHeight = $gSrcHeight * $gSrcCount + 109
$hGUI = GUICreate("Поиск и замена", 563, $nGUIHeight, -1, @DesktopHeight/2 - $nGUIHeight/2)
GUICtrlCreateLabel("Маска файлов", 8, 6, 78, 17)
$edMask = GUICtrlCreateInput("*.*", 8, 24, 265, 21)
GUICtrlCreateLabel("Текст для поиска", 8, 54, 94, 17)
GUICtrlCreateLabel("Текст для замены", 288, 54, 98, 17)
For $i = 0 To $gSrcCount - 1
$gSrcEdit[$i] = GUICtrlCreateEdit("", 8, 72 + $gSrcHeight * $i, 265, $gSrcHeight)
Next
$edTrg = GUICtrlCreateEdit("", 288, 72, 265, $gSrcHeight * $gSrcCount)
$cbCaseSence = GUICtrlCreateCheckbox("Учитывать регистр", 8, $gSrcHeight * $gSrcCount + 84, 137, 17)
$btnOK = GUICtrlCreateButton("OK", 400, $gSrcHeight * $gSrcCount + 79, 75, 25)
$btnCancel = GUICtrlCreateButton("Отмена", 480, $gSrcHeight * $gSrcCount + 79, 75, 25)
GUISetState(@SW_SHOW)
If $aList[0] = 0 Then GUICtrlSetState($btnOK, $GUI_DISABLE)
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE, $btnCancel
Exit
Case $btnOK
$gMask = _MaskToRegexp(GUICtrlRead($edMask))
For $i = 1 To $aList[0]
If StringRight($aList[$i], 1) = "\" Then
_DoFolder($aList[$i])
Else
_DoFile($aList[$i])
EndIf
Next
MsgBox (0, "", "Выполнено замен: " & $gReplaces, 0, $hGUI)
Exit
EndSwitch
WEnd
Func _DoFolder($sFolder)
If $sFolder = "" Then Return
Local $sDirs = ""
Local $hSearch = FileFindFirstFile($sFolder & "*.*")
If @error Then Return
While 1
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
If @extended Then
$sDirs &= $sFolder & $sFile & "\" & @LF
ContinueLoop
EndIf
_DoFile($sFolder & $sFile)
Wend
FileClose($hSearch)
; Обработку каталогов приходится делать отдельно,
; чтобы не оставлять открытый поисковый хэндл,
; их максимально может быть 64
$aDirs = StringSplit($sDirs, @LF)
For $i = 1 To $aDirs[0]
_DoFolder($aDirs[$i])
Next
EndFunc
Func _DoFile($sFile)
If StringRegExp($sFile, $gMask) = 0 Then Return
Local $sText = FileRead($sFile)
Local $sSrc
MsgBox(0, "title", $sText)
Local $nReplaces = 0
For $i = 0 To $gSrcCount - 1
$sSrc = GUICtrlRead($gSrcEdit[$i])
If $sSrc = "" Then ContinueLoop
$sText = StringReplace($sText, $sSrc, GUICtrlRead($edTrg), 0, _
BitAND(GUICtrlRead($cbCaseSence), $GUI_CHECKED))
$nReplaces += @extended
Next
If $nReplaces = 0 Then Return
$gReplaces += $nReplaces
Local $hFile = FileOpen($sFile, 2)
FileWrite($hFile, $sText)
FileClose($hFile)
EndFunc
Func _MaskToRegexp($sMask)
$sMask = StringRegExpReplace($sMask, "(\\|\.|\+|\^|\(|\)|\[|\]|\{|\}|\$)", "\\\1")
$sMask = StringReplace($sMask, "?", ".")
$sMask = StringReplace($sMask, "*", ".+?")
Return("(?i)^" & $sMask & "$")
EndFunc
Func _TCHLoadFileList($sFileName)
Local $asList[1] = [0]
Local $hfList = FileOpen($sFileName, 0)
While 1
$sLine = FileReadLine($hfList)
If @error Then Exitloop
ReDim $asList[UBound($asList)+1]
$asList[UBound($asList)-1] = $sLine
Wend
FileClose($hfList)
$asList[0] = UBound($asList)-1
Return $asList
EndFunc
Добавлено: Вт окт 05, 2010 22:03
Rodny
Batya
Спасибо, самое то. Надо будет всё-таки прочитать ридми дальше, чем до SendCommand
Samwatas
Спасибо, для моих скромных нужд хелпера пока вполне хватит. У меня мало-мальски опыт с VB есть, а вот на знакомство с автоитом пока времени взять негде.
Добавлено: Вт окт 05, 2010 22:36
Lev
Lev
Дык, по-моему, тоже со строками только работает.
По-твоему.
Переведи на русский слово Multiline.
Ответь на вопрос - зачем в регекспах всякие: ^ Line start, $ Line end, \r, \n при построчной работе?
Добавлено: Ср окт 06, 2010 04:52
Flasher
Loopback
С таблицей, я так понял, не получилось, жаль.
Loopback писал(а):Параметры интерфейса можно задать в начале скрипта, думаю там все понятно.
Э..э, а как же?:
Flasher писал(а):хотелось бы (если это возможно) разбивать левое окно на заданное в параметрах кол-во частей
Я же не буду для каждого случая компилить a3x-файл

.

А ещё лучше, если сперва будет появляться маленькое окошко с 6-9 кнопочками с номерами, при нажатии на каждое из которых будет появляться окно, где левая часть разбита на сопоставленное с номером кол-во частей.
Lev
Ок, с этим всё понятно. Если есть возможность, сделай скрипт по аналогии со скриптом Volniy(+Batya) с использованием VBScript.RegExp и objRegExp.Multiline, а мы оценим.
Добавлено: Ср окт 06, 2010 13:10
Samwatas
Скопируй содержимое файла GUIConstantsEx.au3 в свой файл скрипта (можно также проредить его, удалив неиспользуемые константы), соответственно не нужно будет ничего компилить.
Добавлено: Ср окт 06, 2010 13:18
Flasher
Это ситуацию никак не изменит, фактически будут те же грабли по временным затратам.