使用子例程或函数减少代码

时间:2015-05-20 06:28:20

标签: vbscript subroutine

我有一个HTA的VBScript代码,发现自己一遍又一遍地复制/粘贴代码。在下面的示例中,CopyCheckList查看下拉列表,并根据数字/步骤调用正确的Step子例程。现在为了避免复制/粘贴相同的代码17次,我希望得到一些使用函数来减少所需代码量的指针。例如,如果上次执行了步骤6,则步骤1-6标记为DONE。

这是我的初学者复制/粘贴代码,但是我确信功能代码可以大大减少复制/粘贴代码的需要,只是为了改变一行文本。

Sub Copychecklist()
  Dim VMBuildStep
  VMBuildStep = document.getElementById("BuildStepChoice").Value
  If VMBuildStep = 1 Then Call Step1 Else
  If VMBuildStep = 2 Then Call Step2 Else
  If VMBuildStep = 3 Then Call Step3 Else
  If VMBuildStep = 4 Then Call Step4 Else
  If VMBuildStep = 5 Then Call Step5 Else
  If VMBuildStep = 6 Then Call Step6 Else
  If VMBuildStep = 7 Then Call Step7 Else
  If VMBuildStep = 8 Then Call Step8 Else
  If VMBuildStep = 9 Then Call Step9 Else
  If VMBuildStep = 10 Then Call Step10 Else
  If VMBuildStep = 11 Then Call Step11 Else
  If VMBuildStep = 12 Then Call Step12 Else
  If VMBuildStep = 13 Then Call Step13 Else
  If VMBuildStep = 14 Then Call Step14 Else
  If VMBuildStep = 15 Then Call Step15 Else
  If VMBuildStep = 16 Then Call Step16 Else
  If VMBuildStep = 17 Then Call Step17 End If
End Sub

Sub Step1()
  Dim sSr, sRequest, oSRSearch, sSvr, sOS, filesys, filetxt
  Set filesys = CreateObject("Scripting.FileSystemObject")
  If filesys.FileExists(filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1") Then
    filesys.DeleteFile (filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1")
  End If
  Const ForReading = 1, ForWriting = 2, ForAppending = 8
  Set filesys = CreateObject("Scripting.FileSystemObject")
  Set filetxt = filesys.OpenTextFile(filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1", ForAppending, True)
  sSvr = document.getElementById("TextBox1").Value
  sRequest = document.getElementByID("TextBox9").Value
  sOS = document.getElementById("TextBox10").Value
  If sRequest = "" Then
    MsgBox "Please enter something in the input form"
    Exit Sub
  End If
  filetxt.WriteLine ("Param(")
  filetxt.WriteLine ("[Parameter(Mandatory=$true)]")
  filetxt.WriteLine ("[string]$SONum,")
  filetxt.WriteLine ("[Parameter(Mandatory=$true)]")
  filetxt.WriteLine ("[string]$svr,")
  filetxt.WriteLine ("[Parameter(Mandatory=$true)]")
  filetxt.WriteLine ("[string]$oschoice)")
  filetxt.WriteLine ("#Here string for VM Build procedure Note")
  filetxt.WriteLine ("$notesub = ""$svr - $oschoice""")
  filetxt.WriteLine ("$notedesc = @'")
  filetxt.WriteLine ("<pre>")
  filetxt.WriteLine ("1).   Create Record: DONE")
  filetxt.WriteLine ("2).   Request static IP Addresses: N/A")
  filetxt.WriteLine ("3).   Create the AD Server Object: ")
  filetxt.WriteLine ("4).   Create the Virtual Machine: ")
  filetxt.WriteLine ("5).   Discover the server and assign the OSD (SCCM): ")
  filetxt.WriteLine ("6).   Install the OS:")
  filetxt.WriteLine ("7).   Local Admin PW:")
  filetxt.WriteLine ("8).   Configure Virtual Disks")
  filetxt.WriteLine ("9).   Install the VMware Tools: ")
  filetxt.WriteLine ("10).  Add Hardware")
  filetxt.WriteLine ("11).  Configure NICs")
  filetxt.WriteLine ("12).  Add to SCCM  SRV-Patching  collection:")
  filetxt.WriteLine ("13).  Import Windows Firewall Policy:")
  filetxt.WriteLine ("14).  NetBackup Agent, Install/Patch and FirewallConfig")
  filetxt.WriteLine ("15).  Install Security Updates")
  filetxt.WriteLine ("16).  Update Reboot Instructions")
  filetxt.WriteLine ("17).  SCOM Maintenance Mode")
  filetxt.WriteLine ("</pre>")
  filetxt.WriteLine ("'@")
  filetxt.WriteLine ("# Create the IE com object")
  filetxt.WriteLine ("$ie = New-Object -ComObject InternetExplorer.Application")
  filetxt.WriteLine ("#Navigate to the Tracker IR search page.")
  filetxt.WriteLine ("$ie.navigate(" & Chr(34) & "http://WebSite.com?SONum=$SONum" & Chr(34) & ")")
  filetxt.WriteLine ("# Wait for the page to finish loading")
  filetxt.WriteLine ("do {sleep 1} until (-not ($ie.Busy))")
  filetxt.WriteLine ("$doc = $ie.document")
  filetxt.WriteLine ("$link = $doc.getElementById(""NoteSub"").Value = ""$notesub""")
  filetxt.WriteLine ("$link = $doc.getElementById(""NoteDesc"").Value = ""$notedesc""")
  filetxt.WriteLine ("$signature = @""")
  filetxt.WriteLine ("  ")
  filetxt.WriteLine ("  [DllImport(""user32.dll"")]")
  filetxt.WriteLine ("  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);  ")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  public static IntPtr FindWindow(string windowName){")
  filetxt.WriteLine ("      return FindWindow(null,windowName);")
  filetxt.WriteLine ("  }")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  [DllImport(""user32.dll"")]")
  filetxt.WriteLine ("  public static extern bool SetWindowPos(IntPtr hWnd,")
  filetxt.WriteLine ("  IntPtr hWndInsertAfter, int X,int Y, int cx, int cy, uint uFlags);")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  [DllImport(""user32.dll"")]")
  filetxt.WriteLine ("  public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);")
  filetxt.WriteLine ("  static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  const UInt32 SWP_NOSIZE = 0x0001;")
  filetxt.WriteLine ("  const UInt32 SWP_NOMOVE = 0x0002;")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  public static void MakeTopMost (IntPtr fHandle)")
  filetxt.WriteLine ("  {")
  filetxt.WriteLine ("      SetWindowPos(fHandle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);")
  filetxt.WriteLine ("  }")
  filetxt.WriteLine ("")
  filetxt.WriteLine ("  public static void MakeNormal (IntPtr fHandle)")
  filetxt.WriteLine ("  {")
  filetxt.WriteLine ("      SetWindowPos(fHandle, HWND_NOTOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);")
  filetxt.WriteLine ("  }")
  filetxt.WriteLine ("""@")
  filetxt.WriteLine ("$hWnd = $ie.HWND")
  filetxt.WriteLine ("$app = Add-Type -MemberDefinition $signature -Name Win32Window -Namespace ScriptFanatic.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru")
  filetxt.WriteLine ("$null = $app::MakeTopMost($hWnd)")
  filetxt.WriteLine ("$null = $app::MakeNormal($hWnd)")
  filetxt.WriteLine ("$ie.Visible = $true")
  filetxt.WriteLine ("$button.click();")
  filetxt.WriteLine ("[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | Out-Null")
  filetxt.Close
  Set oSRSearch  = CreateObject("WScript.Shell")
  sSr      = "powershell.exe " & filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1 " & Chr(39) & sRequest & Chr(39) & " " & Chr(39) & sSvr & Chr(39) & " " & Chr(39) & sOS & Chr(39)
  oSRSearch.Run sSr, 0, true
  filesys.DeleteFile (filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1")
End Sub

2 个答案:

答案 0 :(得分:1)

我无法对此进行测试,因为您的代码需要的其他内容不在您发布的内容中,但无论如何,这是我的修改以减少它:

Sub Copychecklist()
Dim VMBuildStep
VMBuildStep = document.getElementById("BuildStepChoice").Value
If (IsNumeric(VMBuildStep)) Then
    VMBuildStep = Int(VMBuildStep)
    If (VMBuildStep >= 1 And VMBuildStep <= 17) Then CreateFile(VMBuildStep)
End If
End Sub

Sub CreateFile(stepNumber)
Dim sSr, sRequest, oSRSearch, sSvr, sOS, filesys, filetxt, resultText(17)
BuildResultText resultText, stepNumber
Set filesys = CreateObject("Scripting.FileSystemObject")
If filesys.FileExists(filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1") Then
 filesys.DeleteFile (filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1")
End If
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.OpenTextFile(filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1", ForAppending, True)
sSvr = document.getElementById("TextBox1").Value
sRequest = document.getElementByID("TextBox9").Value
sOS = document.getElementById("TextBox10").Value
If sRequest = "" Then
 MsgBox "Please enter something in the input form"
 Exit Sub
End If
filetxt.WriteLine ("Param(")
filetxt.WriteLine ("[Parameter(Mandatory=$true)]")
filetxt.WriteLine ("[string]$SONum,")
filetxt.WriteLine ("[Parameter(Mandatory=$true)]")
filetxt.WriteLine ("[string]$svr,")
filetxt.WriteLine ("[Parameter(Mandatory=$true)]")
filetxt.WriteLine ("[string]$oschoice)")
filetxt.WriteLine ("#Here string for VM Build procedure Note")
filetxt.WriteLine ("$notesub = ""$svr - $oschoice""")
filetxt.WriteLine ("$notedesc = @'")
filetxt.WriteLine ("<pre>")
filetxt.WriteLine ("1). Create Record: ") & resultText(0)
filetxt.WriteLine ("2). Request static IP Addresses: ")  & resultText(1)
filetxt.WriteLine ("3). Create the AD Server Object: ") & resultText(2)
filetxt.WriteLine ("4). Create the Virtual Machine: ") & resultText(3)
filetxt.WriteLine ("5). Discover the server and assign the OSD (SCCM): ") & resultText(4)
filetxt.WriteLine ("6). Install the OS: ") & resultText(5)
filetxt.WriteLine ("7). Local Admin PW: ") & resultText(6)
filetxt.WriteLine ("8). Configure Virtual Disks: ") & resultText(7)
filetxt.WriteLine ("9). Install the VMware Tools: ") & resultText(8)
filetxt.WriteLine ("10).    Add Hardware: ") & resultText(9)
filetxt.WriteLine ("11).    Configure NICs: ") & resultText(10)
filetxt.WriteLine ("12).    Add to SCCM  SRV-Patching  collection: ") & resultText(11)
filetxt.WriteLine ("13).    Import Windows Firewall Policy: ") & resultText(12)
filetxt.WriteLine ("14).    NetBackup Agent, Install/Patch and FirewallConfig: ") & resultText(13)
filetxt.WriteLine ("15).    Install Security Updates: ") & resultText(14)
filetxt.WriteLine ("16).    Update Reboot Instructions: ") & resultText(15)
filetxt.WriteLine ("17).    SCOM Maintenance Mode: ") & resultText(16)
filetxt.WriteLine ("</pre>")
filetxt.WriteLine ("'@")
filetxt.WriteLine ("# Create the IE com object")
filetxt.WriteLine ("$ie = New-Object -ComObject InternetExplorer.Application")
filetxt.WriteLine ("#Navigate to the Tracker IR search page.")
filetxt.WriteLine ("$ie.navigate(" & Chr(34) & "http://WebSite.com?SONum=$SONum" & Chr(34) & ")")
filetxt.WriteLine ("# Wait for the page to finish loading")
filetxt.WriteLine ("do {sleep 1} until (-not ($ie.Busy))")
filetxt.WriteLine ("$doc = $ie.document")
filetxt.WriteLine ("$link = $doc.getElementById(""NoteSub"").Value = ""$notesub""")
filetxt.WriteLine ("$link = $doc.getElementById(""NoteDesc"").Value = ""$notedesc""")
filetxt.WriteLine ("$signature = @""")
filetxt.WriteLine ("    ")
filetxt.WriteLine ("    [DllImport(""user32.dll"")]")
filetxt.WriteLine ("    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);  ")
filetxt.WriteLine ("")
filetxt.WriteLine ("    public static IntPtr FindWindow(string windowName){")
filetxt.WriteLine ("        return FindWindow(null,windowName);")
filetxt.WriteLine ("    }")
filetxt.WriteLine ("")
filetxt.WriteLine ("    [DllImport(""user32.dll"")]")
filetxt.WriteLine ("    public static extern bool SetWindowPos(IntPtr hWnd,")
filetxt.WriteLine ("    IntPtr hWndInsertAfter, int X,int Y, int cx, int cy, uint uFlags);")
filetxt.WriteLine ("")
filetxt.WriteLine ("    [DllImport(""user32.dll"")]")
filetxt.WriteLine ("    public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);")
filetxt.WriteLine ("")
filetxt.WriteLine ("    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);")
filetxt.WriteLine ("    static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);")
filetxt.WriteLine ("")
filetxt.WriteLine ("    const UInt32 SWP_NOSIZE = 0x0001;")
filetxt.WriteLine ("    const UInt32 SWP_NOMOVE = 0x0002;")
filetxt.WriteLine ("")
filetxt.WriteLine ("    const UInt32 TOPMOST_FLAGS = SWP_NOMOVE | SWP_NOSIZE;")
filetxt.WriteLine ("")
filetxt.WriteLine ("    public static void MakeTopMost (IntPtr fHandle)")
filetxt.WriteLine ("    {")
filetxt.WriteLine ("        SetWindowPos(fHandle, HWND_TOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);")
filetxt.WriteLine ("    }")
filetxt.WriteLine ("")
filetxt.WriteLine ("    public static void MakeNormal (IntPtr fHandle)")
filetxt.WriteLine ("    {")
filetxt.WriteLine ("        SetWindowPos(fHandle, HWND_NOTOPMOST, 0, 0, 0, 0, TOPMOST_FLAGS);")
filetxt.WriteLine ("    }")
filetxt.WriteLine ("""@")
filetxt.WriteLine ("$hWnd = $ie.HWND")
filetxt.WriteLine ("$app = Add-Type -MemberDefinition $signature -Name Win32Window -Namespace ScriptFanatic.WinAPI -ReferencedAssemblies System.Windows.Forms -Using System.Windows.Forms -PassThru")
filetxt.WriteLine ("$null = $app::MakeTopMost($hWnd)")
filetxt.WriteLine ("$null = $app::MakeNormal($hWnd)")
filetxt.WriteLine ("$ie.Visible = $true")
filetxt.WriteLine ("$button.click();")
filetxt.WriteLine ("[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | Out-Null")
filetxt.Close
Set oSRSearch  = CreateObject("WScript.Shell")
 sSr      = "powershell.exe " & filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1 " & Chr(39) & sRequest & Chr(39) & " " & Chr(39) & sSvr & Chr(39) & " " & Chr(39) & sOS & Chr(39)
 oSRSearch.Run sSr, 0, true
 filesys.DeleteFile (filesys.GetSpecialFolder(2) & "\powershell-VM-SR-search.ps1")
End Sub

Sub BuildResultText(resultText, stepNumber)
    Dim i 
    For i = 0 To UBound(resultText)
        If (i < stepNumber) Then
            resultText(i) = "DONE"
        Else
            resultText(i) = ""
        End If
    Next
End Sub

我将Step1子项更改为单个“整体”子,其中以步骤编号作为参数。它为步骤结果文本创建一个数组,并调用另一个子用“DONE”填充小于或等于步骤编号的任何步骤,或者对于任何大于当前步骤的步骤(当然可以更改)是有意义的事情)。

因此,重命名的子现在只运行其正常的东西,并根据数组填充步骤结果文本。

最后,我删除了第一个sub中的所有if / else语句,并将其替换为单个语句。

修改

我删除了大部分代码并留下足以测试数组文本,并按预期输出 - “DONE”仅在前四个循环中输出。

Copychecklist()

Sub Copychecklist()
Dim VMBuildStep : VMBuildStep = "4"
If (IsNumeric(VMBuildStep)) Then
    VMBuildStep = Int(VMBuildStep)
    If (VMBuildStep >= 1 And VMBuildStep <= 17) Then CreateFile(VMBuildStep)
End If
End Sub

Sub CreateFile(stepNumber)
Dim resultText(17)
BuildResultText resultText, stepNumber
Dim i
For i = 0 To UBound(resultText)
    WScript.Echo "result: " & resultText(i)
Next
End Sub

Sub BuildResultText(resultText, stepNumber)
    Dim i 
    For i = 0 To UBound(resultText)
        If (i < stepNumber) Then
            resultText(i) = "DONE"
        Else
            resultText(i) = ""
        End If
    Next
End Sub

答案 1 :(得分:0)

如果我理解你的问题,你会问你如何制定StepX程序,以便在这一部分:

filetxt.WriteLine ("1).   Create Record: DONE")
filetxt.WriteLine ("2).   Request static IP Addresses: N/A")
filetxt.WriteLine ("3).   Create the AD Server Object: ")
filetxt.WriteLine ("4).   Create the Virtual Machine: ")
filetxt.WriteLine ("5).   Discover the server and assign the OSD (SCCM): ")
filetxt.WriteLine ("6).   Install the OS:")
filetxt.WriteLine ("7).   Local Admin PW:")
filetxt.WriteLine ("8).   Configure Virtual Disks")
filetxt.WriteLine ("9).   Install the VMware Tools: ")
filetxt.WriteLine ("10).  Add Hardware")
filetxt.WriteLine ("11).  Configure NICs")
filetxt.WriteLine ("12).  Add to SCCM  SRV-Patching  collection:")
filetxt.WriteLine ("13).  Import Windows Firewall Policy:")
filetxt.WriteLine ("14).  NetBackup Agent, Install/Patch and FirewallConfig")
filetxt.WriteLine ("15).  Install Security Updates")
filetxt.WriteLine ("16).  Update Reboot Instructions")
filetxt.WriteLine ("17).  SCOM Maintenance Mode")

编号项目标记为DONE,直至当前步骤编号。假设情况如此,您可以执行以下操作。

首先使用操作标签创建dictionary(在全局范围内):

Set actions = CreateObject("Scripting.Dictionary")
actions.Add 1,  "Create Record"
actions.Add 2,  "Request static IP Addresses"
actions.Add 3,  "Create the AD Server Object"
actions.Add 4,  "Create the Virtual Machine"
actions.Add 5,  "Discover the server and assign the OSD (SCCM)"
actions.Add 6,  "Install the OS"
actions.Add 7,  "Local Admin PW"
actions.Add 8,  "Configure Virtual Disks"
actions.Add 9,  "Install the VMware Tools"
actions.Add 10, "Add Hardware"
actions.Add 11, "Configure NICs"
actions.Add 12, "Add to SCCM  SRV-Patching  collection"
actions.Add 13, "Import Windows Firewall Policy"
actions.Add 14, "NetBackup Agent, Install/Patch and FirewallConfig"
actions.Add 15, "Install Security Updates"
actions.Add 16, "Update Reboot Instructions"
actions.Add 17, "SCOM Maintenance Mode"

使用VMBuildStep作为参数调用构建文件的过程,正如@eurotrash在其答案中建议的那样:

If VMBuildStep >= 1 And VMBuildStep <= actions.Count Then
  CreateFile VMBuildStep
Else
  'invalid build step number, put some error handling here
End If

条件是可选的(您也可以调用CreateFile VMBuildStep),但最好有一个安全网并在出现意外情况时进行错误处理。

CreateFile内部构建构建步骤列表,如下所示:

Sub CreateFile(stepNumber)
  ...
  For i = 1 To actions.Count
    filetxt.Write Left(i & ").   ", 6) & actions(i) & ": "
    If i <= stepNumber Then filetxt.Write "DONE"
    filetxt.WriteLine
  Next
  ...
End Sub