Что нового

Как можно сократить подобные или одинаковые участки кода?

eus_deus

Новичок
Сообщения
118
Репутация
0
Привет. Собственно, вопрос в названии.
Имеем код (взят с рабочего скрипта):
Код:
Switch $VisibleAppCheck
        Case 0 To 1
            If MsgBox (4132, 'Вопрос системы', 'Выключить комп после завершения закачки выбранных программ?') = 6 Then _pitanie()
            GUICtrlSetState ($Label4, $GUI_SHOW)
            For $i=1 To $cntnmb3[0]
                GUICtrlSetData ($Label4, 'Получение ссылок... '&$i&' из '&$cntnmb3[0])
                $Pr = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 1) ;; название программы (как отображается в списке)
                $id =  _ArraySearch($aAppsCh, $Pr, 0, 0, 0, 1, 1, 1)
                $sAppsCh = StringSplit($aAppsCh[$id][1], '|')
                $Pr = $sAppsCh[3];; название программы (как отображается на сайте)
                If $Pr = 'Machete' Then   
                    $PrVUpd = StringRegExpReplace(_GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3), '(\d\.)(\d)(\.)(\d+)', '\1\2 Build \4')
                Else
                    $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3) ;; версия  программы на сайте
                EndIf
                $PrV = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 2) ;; версия  программы
                $Source = _InetGetSource ($acnturl[$i], True)
                $Source = _Encoding_CyrillicTo1251($Source)
                If StringInStr ($Source, 'uploadrar.com') Then
                    $Fshare=StringRegExp($Source,'(?si)entry-content(.+?)entry-footer', 1) ;; границы поиска ссылки
                    $Fshare = _ArrayToString($Fshare)
                    $Fshare = StringRegExpReplace($Fshare,'(?is).+('&$Pr&'.+'&$PrVUpd&'.+(?:Зеркало|Uploadrar)\<\/a\>).+','\1') ;; кусок кода с программой и ссылкой
                    $Fshare = StringRegExpReplace($Fshare,'(?is).+href=\h*"(.+?)".+','\1') ;; непосредственно ссылка на файлообменник
                    $oIE = _IECreate($Fshare,0,0)
                    $aLink = _IEGetObjByName($oIE, 'method_free')
                    $aLink.Click()
                    _IELoadWait($oIE, 1000, 5000)
                    Sleep(15000)
                    $oLink = _IEGetObjById($oIE, 'downloadbtn')
                    $oLink.Click()
                    _IELoadWait($oIE, 1000, 5000)
                    $oDirect_Link = _IEGetObjById($oIE, 'direct_link')
                    $sDirect_Link = $oDirect_Link.ChildNodes.Item(0).href
                    $sFinLink &= $sDirect_Link&'|'
                    $sFinName &= $cnttxt[$i]&'|'
                    _IEQuit($oIE)
                Else
                    ContinueLoop
                EndIf
            Next
            GUISetState (@SW_MINIMIZE, $Form8)
            $aFinLink = StringSplit(StringTrimRight($sFinLink, 1), '|')
            $aFinName = StringSplit(StringTrimRight($sFinName, 1), '|')
            For $i=1 To $aFinLink[0]
                $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3) ;; версия  программы на сайте
                $PrV = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 2) ;; версия  программы
                 ProgressOn('Скачивание файла', $aFinName[$i], '0 %', -1, -1, 16)
                 $hDownload = InetGet($aFinLink[$i], $sPathApps&'\'&StringRegExpReplace($aFinLink[$i],'(^.*)\/(.*)$','\2'), 3, 1)
                Do
                    If InetGetInfo($hDownload, 1) Then
                        $iPersent = Round((InetGetInfo($hDownload, 0) / InetGetInfo($hDownload, 1)) * 100)
                        ProgressSet($iPersent, $PrV&'  --> ' &$PrVUpd&@CRLF&$iPersent & ' %, ' & _WinAPI_StrFormatByteSize(InetGetInfo($hDownload, 0)) &     ' (' & _WinAPI_StrFormatByteSize(InetGetInfo($hDownload, 1)) & ')')
                    EndIf
                    Sleep(500)
                Until InetGetInfo($hDownload, 2)
                InetClose($hDownload)
                ProgressOff()
                Sleep(5000)
            Next
            If $DelOldVers = '1'  Then _deldub_arch()
        Case 3
            If MsgBox (4132, 'Вопрос системы', 'Выключить комп после завершения закачки и установки выбранных программ?') = 6 Then _pitanie()
            GUISetState (@SW_HIDE, $Form8)
            Opt("TrayMenuMode", 1 + 2)
            TraySetState(4)
            TraySetIcon($Icons, 14)
            TraySetToolTip ("")
            TraySetToolTip ("Получение ссылок на программы... ")
            For $i=1 To $cntnmb3[0]
                $Pr = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 1) ;; название программы (как отображается в списке)
                $id =  _ArraySearch($aAppsCh, $Pr, 0, 0, 0, 1, 1, 1)
                $sAppsCh = StringSplit($aAppsCh[$id][1], '|')
                $Pr = $sAppsCh[3];; название программы (как отображается на сайте)
                If $Pr = 'Machete' Then   
                    $PrVUpd = StringRegExpReplace(_GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3), '(\d\.)(\d)(\.)(\d+)', '\1\2 Build \4')
                Else
                    $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3) ;; версия  программы на сайте
                EndIf
                $PrV = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 2) ;; версия  программы
                $Source = _InetGetSource ($acnturl[$i], True)
                $Source = _Encoding_CyrillicTo1251($Source)
                If StringInStr ($Source, 'uploadrar.com') Then
                    $Fshare=StringRegExp($Source,'(?si)entry-content(.+?)entry-footer', 1) ;; границы поиска ссылки
                    $Fshare = _ArrayToString($Fshare)
                    $Fshare = StringRegExpReplace($Fshare,'(?is).+('&$Pr&'.+'&$PrVUpd&'.+(?:Зеркало|Uploadrar)\<\/a\>).+','\1') ;; кусок кода с программой и ссылкой
                    $Fshare = StringRegExpReplace($Fshare,'(?is).+href=\h*"(.+?)".+','\1') ;; непосредственно ссылка на файлообменник
                    $oIE = _IECreate($Fshare,0,0)
                    $aLink = _IEGetObjByName($oIE, 'method_free')
                    $aLink.Click()
                    _IELoadWait($oIE, 1000, 5000)
                    Sleep(15000)
                    $oLink = _IEGetObjById($oIE, 'downloadbtn')
                    $oLink.Click()
                    _IELoadWait($oIE, 1000, 5000)
                    $oDirect_Link = _IEGetObjById($oIE, 'direct_link')
                    $sDirect_Link = $oDirect_Link.ChildNodes.Item(0).href
                    $sFinLink &= $sDirect_Link&'|'
                    $sFinName &= $cnttxt[$i]&'|'
                    _IEQuit($oIE)
                Else
                    ContinueLoop
                EndIf
            Next


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

IMStrelcov

CTPEJIbLLOB
Сообщения
258
Репутация
66
так же, если нужно чтобы функция вернула несколько значений, можно исрользовать Byref, тогда переменные переданные в функцию будут изменены и ничего возращать не нужно, ну кроме значения какого либо для того чтобы понять все ок или ошибка.
 
Автор
E

eus_deus

Новичок
Сообщения
118
Репутация
0
Да нет, функция должна вернуть значение. Пробовал повторяющееся участок вынести отдельно и вставить на его место его же, но вписанный в функцию. Итог - все сыпется

Получилось реализовать как то так.
Вот повторяющийся в примере отрезок ( с некоторыми различиями, о них -ниже):
Код:
For $i=1 To $cntnmb3[0]
                If MsgBox (4132, 'Вопрос системы', 'Выключить комп после завершения закачки выбранных программ?') = 6 Then _pitanie()
                GUICtrlSetState ($Label4, $GUI_SHOW)
                $Pr = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 1) ;; название программы (как отображается в списке)
                $id =  _ArraySearch($aAppsCh, $Pr, 0, 0, 0, 1, 1, 1)
                $sAppsCh = StringSplit($aAppsCh[$id][1], '|')
                $Pr = $sAppsCh[3];; название программы (как отображается на сайте)
                If $Pr = 'Machete' Then    
                    $PrVUpd = StringRegExpReplace(_GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3), '(\d\.)(\d)(\.)(\d+)', '\1\2 Build \4') 
                Else
                    $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3) ;; версия  программы на сайте
                EndIf
                $PrV = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 2) ;; версия  программы
                $Source = _InetGetSource ($acnturl[$i], True)
                $Source = _Encoding_CyrillicTo1251($Source)
                If StringInStr ($Source, 'uploadrar.com') Then
                    $Fshare=StringRegExp($Source,'(?si)entry-content(.+?)entry-footer', 1) ;; границы поиска ссылки
                    $Fshare = _ArrayToString($Fshare)
                    $Fshare = StringRegExpReplace($Fshare,'(?is).+('&$Pr&'.+'&$PrVUpd&'.+(?:Зеркало|Uploadrar)\<\/a\>).+','\1') ;; кусок кода с программой и ссылкой
                    $Fshare = StringRegExpReplace($Fshare,'(?is).+href=\h*"(.+?)".+','\1') ;; непосредственно ссылка на файлообменник
                    $oIE = _IECreate($Fshare,0,0)
                    $aLink = _IEGetObjByName($oIE, 'method_free')
                    $aLink.Click()
                    _IELoadWait($oIE, 1000, 5000)
                    Sleep(15000)
                    $oLink = _IEGetObjById($oIE, 'downloadbtn')
                    $oLink.Click()
                    _IELoadWait($oIE, 1000, 5000)
                    $oDirect_Link = _IEGetObjById($oIE, 'direct_link')
                    $sDirect_Link = $oDirect_Link.ChildNodes.Item(0).href
                    $sFinLink &= $sDirect_Link&'|'
                    $sFinName &= $cnttxt[$i]&'|'
                    _IEQuit($oIE)
                Else
                    ContinueLoop
                EndIf
            Next

Для дальнейшей работы нужны значения переменных $sFinLink и $sFinName, которые и должна вернуть функция
Простой вынос отрезка в отдельную функцию с объявлением локальных переменных результата не дает (да и глобальных тоже)
Пишу так:
Код:
Func _download($MSGB, $LBL, $Ids)
    Local $Pr, $PrVUpd, $PrV,  $Source, $Fshare, $oIE, $oLink, $aLink, $oDirect_Link, $sDirect_Link, $sFinLink, $sFinName
    If $MSGB = 6 Then _pitanie()
    If $LBL = 1 Then GUICtrlSetState ($Ids, $GUI_SHOW)
    For $i=1 To $cntnmb3[0]
        If $LBL = 1 Then GUICtrlSetData ($Ids, 'Получение ссылок... '&$i&' из '&$cntnmb3[0])
        $Pr = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 1) ;; название программы (как отображается в списке)
        $id =  _ArraySearch($aAppsCh, $Pr, 0, 0, 0, 1, 1, 1)
        $sAppsCh = StringSplit($aAppsCh[$id][1], '|')
        $Pr = $sAppsCh[3];; название программы (как отображается на сайте)
        If $Pr = 'Machete' Then   
            $PrVUpd = StringRegExpReplace(_GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3), '(\d\.)(\d)(\.)(\d+)', '\1\2 Build \4')
        Else
            $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3) ;; версия  программы на сайте
        EndIf
        $PrV = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 2) ;; версия  программы
        $Source = _InetGetSource ($acnturl[$i], True)
        $Source = _Encoding_CyrillicTo1251($Source)
        If StringInStr ($Source, 'uploadrar.com') Then
            $Fshare=StringRegExp($Source,'(?si)entry-content(.+?)entry-footer', 1) ;; границы поиска ссылки
            $Fshare = _ArrayToString($Fshare)
            $Fshare = StringRegExpReplace($Fshare,'(?is).+('&$Pr&'.+'&$PrVUpd&'.+(?:Зеркало|Uploadrar)\<\/a\>).+','\1') ;; кусок кода с программой и ссылкой
            $Fshare = StringRegExpReplace($Fshare,'(?is).+href=\h*"(.+?)".+','\1') ;; непосредственно ссылка на файлообменник
            $oIE = _IECreate($Fshare,0,0)
            $aLink = _IEGetObjByName($oIE, 'method_free')
            $aLink.Click()
            _IELoadWait($oIE, 1000, 5000)
            Sleep(15000)
            $oLink = _IEGetObjById($oIE, 'downloadbtn')
            $oLink.Click()
            _IELoadWait($oIE, 1000, 5000)
            $oDirect_Link = _IEGetObjById($oIE, 'direct_link')
            $sDirect_Link = $oDirect_Link.ChildNodes.Item(0).href
            $sFinLink &= $sDirect_Link&'|'
            $sFinName &= $cnttxt[$i]&'|'
            _IEQuit($oIE)
        Else
            ContinueLoop
        EndIf
    Next
    $a = $sFinLink&'#'&$sFinName
    Return $a
EndFunc

То есть две переменные вписываю в одну строку через разделитель, и командой return отправляю их далее.
Потом:
Код:
_download(MsgBox (4132, 'Вопрос системы', 'Выключить комп после завершения закачки выбранных программ?'), 1, $Label4) ;собственно вызов с параметрами
            $sFin = StringSplit($a, '#')
            $aFinLink = StringSplit(StringTrimRight($sFin[1], 1), '|')
            $aFinName = StringSplit(StringTrimRight($sFin[2], 1), '|') ;ну и снова разбиение на нужные мне переменные

Поправьте, в чем я не прав. Но так работает
 
Последнее редактирование:

IMStrelcov

CTPEJIbLLOB
Сообщения
258
Репутация
66
переменные передаешь функции, а в функции используешь ByRef
Это позволит изменить и вернуть данные в эти же переменные.
пример:
Код:
$var_1 = 1
$var_2 = 2

ConsoleWrite('$var_1 = ' & $var_1 & @CRLF)
ConsoleWrite('$var_2 = ' & $var_2 & @CRLF)
ConsoleWrite('---------------' & @CRLF)

func1_($var_1, $var_2)

ConsoleWrite('$var_1 = ' & $var_1 & @CRLF)
ConsoleWrite('$var_2 = ' & $var_2 & @CRLF)
ConsoleWrite('---------------' & @CRLF)

Func func1_(ByRef $val_1, ByRef $val_2)
   $val_1 = $val_1 * 10
   $val_2 = $val_2 * 10
EndFunc

если использовать ByRef то в функцию передавать только переменные, а не какие либо не объявленные данные.
Т.Е.
Код:
func1_(1, 2)

не будет работать правильно.


Возможно не будет работать так как я не могу знать какие переменные глобальные, а какие нет, чтобы реализовать их передачу в функцию.
Код:
Global $sFinLink, $sFinName

;##########################################################################################################

Switch $VisibleAppCheck
   Case 0 To 1
      If MsgBox (4132, 'Вопрос системы', 'Выключить комп после завершения закачки выбранных программ?') = 6 Then _pitanie()
      GUICtrlSetState ($Label4, $GUI_SHOW)
      Function_($cntnmb3, 1)
      GUISetState (@SW_MINIMIZE, $Form8)
      $aFinLink = StringSplit(StringTrimRight($sFinLink, 1), '|')
      $aFinName = StringSplit(StringTrimRight($sFinName, 1), '|')
      For $i=1 To $aFinLink[0]
         $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 3) ;; версия  программы на сайте
         $PrV = _GUICtrlListView_GetItemText($hFilelist2, $cntnmb3[$i]-1, 2) ;; версия  программы
         ProgressOn('Скачивание файла', $aFinName[$i], '0 %', -1, -1, 16)
         $hDownload = InetGet($aFinLink[$i], $sPathApps&'\'&StringRegExpReplace($aFinLink[$i],'(^.*)\/(.*)$','\2'), 3, 1)
         Do
            If InetGetInfo($hDownload, 1) Then
               $iPersent = Round((InetGetInfo($hDownload, 0) / InetGetInfo($hDownload, 1)) * 100)
               ProgressSet($iPersent, $PrV&'  --> ' &$PrVUpd&@CRLF&$iPersent & ' %, ' & _WinAPI_StrFormatByteSize(InetGetInfo($hDownload, 0)) &     ' (' & _WinAPI_StrFormatByteSize(InetGetInfo($hDownload, 1)) & ')')
            EndIf
            Sleep(500)
         Until InetGetInfo($hDownload, 2)
         InetClose($hDownload)
         ProgressOff()
         Sleep(5000)
      Next
      If $DelOldVers = '1'  Then _deldub_arch()
   Case 3
      If MsgBox (4132, 'Вопрос системы', 'Выключить комп после завершения закачки и установки выбранных программ?') = 6 Then _pitanie()
      GUISetState (@SW_HIDE, $Form8)
      Opt("TrayMenuMode", 1 + 2)
      TraySetState(4)
      TraySetIcon($Icons, 14)
      TraySetToolTip ("")
      TraySetToolTip ("Получение ссылок на программы... ")
      Function_($cntnmb3, 0)
EndSwitch

;##############################################################################################################

Func Function_(ByRef $_cntnmb3, $_iLabelUpdateProgress = 0)
   $sFinLink = ''
   $sFinName = ''
   Local $oIE, $sDirect_Link, $oDirect_Link, $oLink, $aLink, $Fshare, $Source, $PrVUpd, $Pr, $id,
   For $i=1 To $_cntnmb3[0]
      If $_iLabelUpdateProgress Then GUICtrlSetData ($Label4, 'Получение ссылок... '&$i&' из '&$_cntnmb3[0])
      $Pr = _GUICtrlListView_GetItemText($hFilelist2, $_cntnmb3[$i]-1, 1) ;; название программы (как отображается в списке)
      $id =  _ArraySearch($aAppsCh, $Pr, 0, 0, 0, 1, 1, 1)
      $sAppsCh = StringSplit($aAppsCh[$id][1], '|')
      $Pr = $sAppsCh[3];; название программы (как отображается на сайте)
      If $Pr = 'Machete' Then
         $PrVUpd = StringRegExpReplace(_GUICtrlListView_GetItemText($hFilelist2, $_cntnmb3[$i]-1, 3), '(\d\.)(\d)(\.)(\d+)', '\1\2 Build \4')
      Else
         $PrVUpd = _GUICtrlListView_GetItemText($hFilelist2, $_cntnmb3[$i]-1, 3) ;; версия  программы на сайте
      EndIf
      $Source = _InetGetSource ($acnturl[$i], True)
      $Source = _Encoding_CyrillicTo1251($Source)
      If StringInStr ($Source, 'uploadrar.com') Then
         $Fshare=StringRegExp($Source,'(?si)entry-content(.+?)entry-footer', 1) ;; границы поиска ссылки
         $Fshare = _ArrayToString($Fshare)
         $Fshare = StringRegExpReplace($Fshare,'(?is).+('&$Pr&'.+'&$PrVUpd&'.+(?:Зеркало|Uploadrar)\<\/a\>).+','\1') ;; кусок кода с программой и ссылкой
         $Fshare = StringRegExpReplace($Fshare,'(?is).+href=\h*"(.+?)".+','\1') ;; непосредственно ссылка на файлообменник
         $oIE = _IECreate($Fshare,0,0)
         $aLink = _IEGetObjByName($oIE, 'method_free')
         $aLink.Click()
         _IELoadWait($oIE, 1000, 5000)
         Sleep(15000)
         $oLink = _IEGetObjById($oIE, 'downloadbtn')
         $oLink.Click()
         _IELoadWait($oIE, 1000, 5000)
         $oDirect_Link = _IEGetObjById($oIE, 'direct_link')
         $sDirect_Link = $oDirect_Link.ChildNodes.Item(0).href
         $sFinLink &= $sDirect_Link&'|'
         $sFinName &= $cnttxt[$i]&'|'
         _IEQuit($oIE)
      Else
         ContinueLoop
      EndIf
   Next
EndFunc
 
Последнее редактирование:
Верх