• VBA_50段代码总结


    '
    '                                                          30个有用的VBA代码
    '目录:
    '1--合理使用数组:
    '2--一次保存并关闭所有工作簿:
    '3--限制光标在特定区域的移动  如果要限制工作表中的滚动区域,可以使用以下代码执行此操作:
    '4--01--将筛选后的数据复制到新工作簿中:
    '4--02--将筛选后的数据复制到新工作簿中--Ivan做的:
    '5--将所有公式转换为选定数据集中的值:
    '6--在单个单元格中获取多个查找值
    '7--显示多个隐藏的工作表:
    '8--隐藏除了活动工作表外的所有工作表:
    '9--用VBA代码按字母的顺序对工作表进行排序
    '10--一次性保护所有的工作表(带密码保护)
    '11--一次性取消所有的工作表保护
    '12--突出显示所选内容中的可选行
    '13--突出显示拼错单词的单元格
    '14--刷新工作簿中的所有透视表
    '15--将所选单元格的字母大小写改为大写
    '16--突出显示有批注的单元格
    '17--将所有公式转换为值
    '18--有公式的单元格锁定
    '19--保护工作簿中所有的工作表(不带密码保护)
    '20--在所选内容中每隔一行后插入一行
    '21--自动在相邻单元格中插入日期和时间戳
    '22--显示所有隐藏的行和列
    '23--取消所有的合并单元格
    '24--保存带有时间戳的工作簿
    '25--将工作表另存为一个PDF文件
    '26--将工作簿另存为单独的PDF文件
    '27--突出显示所选数据集中的空白单元格
    '28--按单列对数据排序
    '29--按多列对数据排序
    '30--如何只从字符串中获取数字部分
    '31--总是在激活特定选项卡的情况下打开工作簿
    '32--根据文件全路径名取文件名
    '33--获取文件名的后缀名 instrrev()函数的使用
    '34--清空某列
    '35--获取数据起始行
    '36--获取某列的最后一行(有数据的最后一行)
    '37--格式化字符串
    '38--利用字典对指定列去重(不改变原列,去重后存到字典的Key中)
    '39--数字转列号字母,
    '40--列号字母转数字
    '41--遍历字典
    '42-1-把两列添加到字典中,其中一列为key,另一列为value
    '42-2-将指定三列的一列作为Key和两外两列作为Value添加到字典中
    '43--loop files
    '44-1--使用一维数组对单元格赋值
    '44-2--使用二维数组对单元格赋值
    '45--使用find()函数代替for each 循环
    '46--读取环境变量的方法1--VBA.environ(name)
    '47--读取环境变量的方法2--readuserenviron(name)
    '48--对合并了的单元格的查找
     

    '1--合理使用数组:
    '先给数组赋值,再通过Application.WorksheetFunction.Transpose(arr)给单元格赋值速度极快于通过循环单元格的方式给单元格直接赋值。
    Sub InputArr()
        Dim start As Double
        start = Timer
        Dim i As Long, arr(1 To 65536) As Long
       
        For i = 1 To 65536
            arr(i) = i
        Next
       
        Range("A1:A65536").Value = Application.WorksheetFunction.Transpose(arr)
        MsgBox "程序运行时间约是 " & Format(Timer - start, "0.00") & "秒。"
    End Sub

    '2--一次保存并关闭所有工作簿:
    Sub CloseAllWorkbooks()
        Dim wb As Workbook
        For Each wb In Workbooks
            wb.Close savechanges:=True
        Next wb
    End Sub
    '3--限制光标在特定区域的移动  如果要限制工作表中的滚动区域,可以使用以下代码执行此操作:
    Private Sub Worksheet_Open()
        Sheets("Sheet1").ScrollArea = "A1:M17"
    End Sub

    '4--01--将筛选后的数据复制到新工作簿中:
    '如果您使用的是一个巨大的数据区域,那么过滤器在分割数据时非常有用。有时,您可能只需要数据区域的一部分。
    '在这种情况下,您可以使用下面的代码将筛选后的数据快速复制到新工作表中。
    Sub CopyFilteredData()
        If ActiveSheet.AutoFilterMode = False Then
            Exit Sub
        End If
        ActiveSheet.AutoFilter.Range.Copy
        Workbooks.Add.Worksheets(1).Paste
        Cells.EntireColumn.AutoFit
    End Sub
    '此代码首先检查是否有任何已筛选的数据,否则,它会复制筛选后的数据,插入新工作簿,并将数据粘贴到其中。
    '4--02--将筛选后的数据复制到新工作簿中--Ivan做的:
    'this function is designed to Filter Apro file to get valid records.
        'If SHAR flag is YES or RSU SO EYSMS flag is YES, we do filtering of Apro file as temp file for further processing.
        'In Apro file, we only pick the record with Relocation Phase having values listed in "Apro Relcation Phase" in "Misc_Config" sheet of parm file.This can be used as a temp file
        'If any error, control report is updated.
    Sub PreApro()
    On Error GoTo errorhandler
        Dim wb_new_apro As Workbook
        Dim ws_new_apro As Worksheet
        Dim int_last_row_parm As Long
        Dim int_last_row_input As Long
        Dim str_filter() As String
        Dim i As Long
        Dim ws_apro_input As Worksheet
       
        My_Err = "PreProcess module error - PreApro sub error."
       
        If Get_SHAR_CheckBox_Flag = True Or Get_RSUSOEYSMS_CheckBox_Flag = True Then
            int_last_row_parm = getLastValidRow(ThisWorkbook.Worksheets("Misc_Config"), "M")
            ReDim str_filter(1 To int_last_row_parm - 1)
            For i = 2 To int_last_row_parm
                str_filter(i - 1) = Trim(ThisWorkbook.Worksheets("Misc_Config").Range("M" & i))
            Next
           
            Set wb_new_apro = Workbooks.Add
            Set ws_new_apro = wb_new_apro.Worksheets(1)
           
            openF2_Apro_File
            Set ws_apro_input = wb_F2_Apro_File.Worksheets(1)
            int_last_row_input = getLastValidRow(ws_apro_input, "A")
            If ws_apro_input.AutoFilterMode = True Then
                ws_apro_input.AutoFilterMode = False
            End If
            ws_apro_input.Range("$A$3:$AF$" & int_last_row_input).AutoFilter Field:=2, Criteria1:=str_filter, Operator:=xlFilterValues
            'ws_apro_input.Range("A1:AF" & int_last_row_input).Copy ws_new_apro.Range("A1")
            ws_apro_input.Range("A1:AF" & int_last_row_input).SpecialCells(xlCellTypeVisible).Copy ws_new_apro.Range("A1")
           
            ws_new_apro.Cells.WrapText = False
            ws_new_apro.Columns("A:AF").AutoFit
           
            ws_new_apro.Name = ws_apro_input.Name
            If verifyFileExist(get_F30_Apro_Filter_File) Then
                Kill get_F30_Apro_Filter_File
            End If
            wb_new_apro.SaveAs Filename:=get_F30_Apro_Filter_File
           
            closeF2_Apro_File False
            wb_new_apro.Close savechanges:=True
        End If
    End Sub
    '5--将所有公式转换为选定数据集中的值:
    '如果要快速将所有具有公式的单元格转换为值,可以使用以下代码:
    Sub ConvertFormulastoValues()
        Dim Myrange As Range
        Dim MyCell As Range
        Set Myrange = Selection
        For Each MyCell In Myrange
            If MyCell.HasFormula Then
            MyCell.Formula = MyCell.Value
        End If
        Next MyCell
    End Sub
    '注意这个变化是不可逆的,公式将无法恢复。
    '或者,你也可以编写一个消息框,显示公式将丢失的警告。这可以防止用户意外运行此宏
    '6--在单个单元格中获取多个查找值
    '如果要查找表中的值并在同一单元格中获取所有匹配结果,则需要使用VBA创建自定义函数。
    '下面是创建了一个公式,类似VLOOKUP。
    Function GetMultipleLookupValues(Lookupvalue As String, LookupRange As Range, ColumnNumber As Integer)
        Dim i As Long
        Dim Result As String
        For i = 1 To LookupRange.Columns(1).Cells.count
            If LookupRange.Cells(i, 1) = Lookupvalue Then
                Result = Result & " " & LookupRange.Cells(i, ColumnNumber) & ","
            End If
        Next i
        GetMultipleLookupValues = Left(Result, Len(Result) - 1)
    End Function
    '注意,这个函数有三个参数:
    'Lookupvalue  – 需要查询的值
    'LookupRange  – 需要查询的区域
    'ColumnNumber – 提取结果的列号
    '7--1.显示多个隐藏的工作表:
    '如果你的工作簿里面有多个隐藏的工作表,你需要花很多时间一个一个的显示隐藏的工作表。
    '下面的代码,可以让你一次显示所有的工作表
    Sub UnhideAllWoksheets()
        Dim ws As Worksheet
        For Each ws In ActiveWorkbook.Worksheets
            ws.Visible = xlSheetVisible
        Next ws
    End Sub
    '8--隐藏除了活动工作表外的所有工作表:
    '如果你做的报表,希望隐藏除了报表工作表以外的所有工作表,则可以用一下代码来实现:
    Sub HideAllExcetActiveSheet()
        Dim ws As Worksheet
        For Each ws In ThisWorkbook.Worksheets
        If ws.Name <> ActiveSheet.Name Then
            ws.Visible = xlSheetHidden
        End If
        Next ws
    End Sub
    '9--用VBA代码按字母的顺序对工作表进行排序
    '如果你有一个包含多个工作表的工作簿,并且希望按字母对工作表进行排序,那么下面的代码,可以派上用场。
    Sub SortSheetsTabName()
        Application.ScreenUpdating = False
        Dim ShCount As Integer, i As Integer, j As Integer
        ShCount = Sheets.count
        For i = 1 To ShCount - 1
            For j = i + 1 To ShCount
                If Sheets(j).Name < Sheets(i).Name Then
                    Sheets(j).Move before:=Sheets(i)
                End If
            Next j
        Next i
        Application.ScreenUpdating = True
    End Sub
    '10--一次性保护所有的工作表(带密码保护)
    '如果工作薄里面有多个工作表,并且希望保护所有的工作表,那么下面的代码,可以派上用场。
    Sub ProtectAllSheets()
        Dim ws As Worksheet
        Dim password As String
        '用你想要的密码替换Test123
        password = "Test123"
        For Each ws In Worksheets
            ws.Protect password:=password
        Next ws
    End Sub
    '11--一次性取消所有的工作表保护
    '如果你保护了你所有的工作表,那么你只需要修改一下代码,就可以取消所有工作表的保护。
    Sub ProtectsAllSheets()
        Dim ws As Worksheet
        Dim password As String
        '用你想要的密码替换Test123
        password = "Test123"
         For Each ws In Worksheets
         ws.Unprotect password:=password
         Next ws
    End Sub
    '需要注意的是,取消保护工作表的密码, 要与锁定工作表的密码相同,否则程序会抛出异常(出错)。
    '12--突出显示所选内容中的可选行
    '突出显示可选行可以极大地提高数据的可读性?
    '下面是一个代码,它将立即突出显示所选内容中的可选行。
    Sub HighlightAlternateRows()
        Dim Myrange As Range
        Dim Myrow As Range
        Set Myrange = Selection
        For Each Myrow In Myrange.Rows
            '将奇数行突出显示
            If Myrow.Row Mod 2 = 1 Then
                Myrow.Interior.Color = vbCyan
            End If
        Next Myrow
    End Sub
    '注意,代码中指定了颜色为vbCyan(也可以修改成:vbRed, vbGreen, vbBlue)。

    '13--突出显示拼错单词的单元格
    'Excel没有像在Word或PowerPoint中那样进行拼写检查。虽然可以按F7键进行拼写检查,但当出现拼写错误时,没有视觉提示。
    '使用此代码可以立即突出显示其中有拼写错误的所有单元格。
    Sub HighlightMisspelledCells()
        Dim cl As Range
        For Each cl In ActiveSheet.UsedRange
            If Not Application.CheckSpelling(word:=cl.Text) Then
                cl.Interior.Color = vbRed
            End If
        Next cl
    End Sub
    '请注意,突出显示的单元格包含Excel认为是拼写错误的文本。当然在许多情况下,它也会显示其它各种错误。
     
    '14--刷新工作簿中的所有透视表
    '如果工作簿中有多个透视表,则可以使用此代码一次刷新所有这些透视表。
    Sub RefreshAllPivotTables()
        Dim PT As PivotTable
        For Each PT In ActiveSheet.PivotTables
            PT.RefreshTable
        Next PT
    End Sub
    '15--将所选单元格的字母大小写改为大写
    '虽然Excel有更改文本字母大小写的公式,但它使您可以在另一组单元格中进行更改。
    '使用此代码可以立即更改所选文本中文本的字母大小写?
    Sub ChangeCase()
        Dim rng As Range
        For Each rng In Selection.Cells
            If rng.HasFormula = False Then
                rng.Value = UCase(rng.Value)
            End If
        Next rng
    End Sub
    '注意,在本例中,使用了UCase将文本大小写设为大写。
    '16--突出显示有批注的单元格
    '使用下面的代码突出显示其中包含注释的所有单元格。
    Sub HighlightCellsWithComments()
        ActiveSheet.Cells.SpecialCells(xlCellTypeComments).Interior.Color = vbBlue
    End Sub
    '在本例中,使用vblue为单元格赋予蓝色。如果你想的话,你可以把这个换成其他颜色。
    '17--将所有公式转换为值
    '如果工作表包含大量公式,并且要将这些公式转换为值,请使用此代码。
    Sub ConvertToValues()
        With ActiveSheet.UsedRange
        .Value = .Value
        End With
    End Sub
    '此代码可以自动将使用公式的值转换为值。

    '18--有公式的单元格锁定
    '当您有大量的计算并且不想意外的删除或更改时,您可能希望使用把有公式的单元格进行锁定。
    '下面是将锁定所有具有公式的单元格的代码,而所有其它单元格都未锁定。
    Sub LockCellsWithFormulas()
        With ActiveSheet
            .Unprotect
            .Cells.Locked = False
            .Cells.SpecialCells(xlCellTypeFormulas).Locked = True
            .Protect AllowDeletingRows:=True
        End With
    End Sub

    '19--保护工作簿中所有的工作表(不带密码保护)
    '使用以下代码一次性保护工作簿中的所有工作表
    Sub ProtectAllSheets2()
        Dim ws As Worksheet
        For Each ws In Worksheets
            ws.Protect
        Next ws
    End Sub
    '此代码将逐个浏览所有工作表并对其进行保护。
    '如果要取消所有工作表的保护,可以使用 ws.unProtect。

    '20--在所选内容中每隔一行后插入一行
    '如果要在选定区域中的每一行后插入空行,请使用此代码。
    Sub InsertAlternateRows()
        Dim rng As Range
        Dim CountRow As Integer
        Dim i As Integer
        Set rng = Selection
        CountRow = rng.EntireRow.count
        For i = 1 To CountRow
            ActiveCell.EntireRow.Insert
            ActiveCell.Offset(2, 0).Select
        Next i
    End Sub
    '同样,您可以修改此代码,以便在所选范围内的每一列之后插入一个空白列

    '21--自动在相邻单元格中插入日期和时间戳
    '当您想要跟踪活动时,可以使用时间戳。
    '使用此代码在创建条目或编辑现有内容时在相邻单元格中插入日期和时间戳。
    Private Sub Worksheet_Change(ByVal Target As Range)
        On Error GoTo Handler
        If Target.Column = 1 And Target.Value <> "" Then
            Application.EnableEvents = False
            Target.Offset(0, 1) = Format(Now(), "dd-mm-yyyy hh:mm:ss")
            Application.EnableEvents = True
        End If
    Handler:
    End Sub
    '请注意,您需要将此代码插入工作表代码窗口(而不是模块内代码窗口)。因为这是一个事件代码

    '22--显示所有隐藏的行和列
    '下面的代码,可以取消所有隐藏的行和列。
    '如果你从别人那里获得一个Excel文件,并希望没有隐藏的行与列,那么下面的代码对你非常有用。
    Sub UnhideRowsColumns()
        Columns.EntireColumn.Hidden = False
        Rows.EntireRow.Hidden = False
    End Sub

    '23--取消所有的合并单元格
    '如果你的工作表里面有合并的单元格,使用下面代码可以一次性取消所有合并的单元格。
    Sub UnmergeAllCells()
        ActiveSheet.Cells.UnMerge
    End Sub
     
    '24--保存带有时间戳的工作簿
    '很多时候,您可能需要创建工作的各个版本。
    '一个好的做法,就是在工作薄名称上,加上时间戳。
    '使用时间戳将允许您返回到某个文件,查看进行了哪些更改或使用了哪些数据。
    '
    '下面的代码会自动保存工作簿在指定的文件夹中 , 并添加一个时间戳时保存。
    Sub SaveWorkbookWithTimeStamp()
        Dim timestamp As String
        timestamp = Format(Date, "dd-mm-yyyy") & "_" & Format(Time, "hh-ss")
        ThisWorkbook.SaveAs "C:UsersUsernameDesktopWorkbookName" & timestamp
    End Sub

    '25--将工作表另存为一个PDF文件
    '如果您使用不同年份或部门或产品的数据,可能需要将不同的工作表保存为PDF文件。
    '如果手动完成,这可能是一个耗时的过程,但vba确可以加快速度。
    '
    '下面是一个将每个工作表保存为单独PDF的VBA代码:
    Sub SaveWorkshetAsPDF()
        Dim ws As Worksheet
        For Each ws In Worksheets
            ws.ExportAsFixedFormat xlTypePDF, "C:UsersUsernameDesktopTest" & ws.Name & ".pdf"
        Next ws
    End Sub
    '请注意,此代码仅适用于工作表,并且需要在工作表里面设置好打印的区域。如果有空的工作表,那么程序会报错

    '26--将工作簿另存为单独的PDF文件
    '下面是将整个工作簿保存为指定文件夹中的PDF格式的代码
    Sub save_WorkshetAsPDF()
        ThisWorkbook.ExportAsFixedFormat xlTypePDF, "C:UsersSumitDesktopTest" & ThisWorkbook.Name & ".pdf"
    End Sub
    '注意:25,26代码保存为PDF文件,需要在工作表里面设置好打印的区域。如果有空的工作表,那么程序会报错。

    '27--突出显示所选数据集中的空白单元格
    '虽然可以使用条件格式或“转到特殊”对话框突出显示空白单元格,但如果必须经常这样做,最好使用宏。
    '创建后,你可以将代码保存在个人宏工作簿中。
    Sub HighlightBlankCells()
        Dim Dataset As Range
        Set Dataset = Selection
        Dataset.SpecialCells(xlCellTypeBlanks).Interior.Color = vbRed
    End Sub
    '在这个代码中,指定了红色单元格中要突出显示的空白单元格。

    '28--按单列对数据排序
    '可以使用下面的代码按指定列对数据排序。
    Sub SortDataHeader()
        Range("DataRange").Sort Key1:=Range("A1"), Order1:=xlAscending, Header:=xlYes
    End Sub
    '请注意,我创建了一个名为“datarange”的命名范围,并使用它来代替单元格引用。
    '这里还使用了三个关键参数: 参照之前的文章

    '29--按多列对数据排序
    '下面是将根据多个列对数据排序的代码(A列先排序,在进行B列排序)。
    Sub SortMultipleColumns()
        With ActiveSheet.Sort
         .SortFields.Add Key:=Range("A1"), Order:=xlAscending
         .SortFields.Add Key:=Range("B1"), Order:=xlAscending
         .SetRange Range("A1:C13")
         .Header = xlYes.Apply
        End With
    End Sub
    '注意,这个代码指定了首先根据A列排序,然后根据B列排序

    '30--如何只从字符串中获取数字部分
    '如果只从字符串中提取数字部分或文本部分,则可以在VBA中创建自定义函数.
    '然后,您可以在工作表中使用这个vba函数(就像普通的Excel函数一样),它将只从字符串中提取数字或文本部分.
    '下面是将创建函数从字符串中提取数字部分的VBA代码:
    Function GetNumeric(CellRef As String)
        Dim StringLength As Integer
        StringLength = Len(CellRef)
        For i = 1 To StringLength
            If IsNumeric(Mid(CellRef, i, 1)) Then
                Result = Result & Mid(CellRef, i, 1)
            End If
        Next i
        GetNumeric = Result
    End Function
    '您需要将代码放入模块中,然后可以在工作表中使用函数"=GetNumeric".
    '此函数只接受一个参数,即要从中获取数值部分的单元格的单元格引用。

    '31--总是在激活特定选项卡的情况下打开工作簿
    '如果要打开一个工作簿,该工作簿总是在特定工作表的情况下打开,则可以使用以下代码。
    '当您希望在工作簿打开时激活指定工作表时,这将非常有用。
    Private Sub Workbook_Open()
        Sheets("Sheet1").Select
    End Sub
    '请注意,此代码需要放在ThisWorkbook对象的“代码”窗口中
    '这意味着当您在VB编辑器中时,需要双击此工作簿对象并复制粘贴其中的代码。

    '32--根据文件全路径名取文件名:
    'InStr 返回一个字符串在另一个字符串中出现的位置。
    'InStrRev 返回一个字符串在另一个字符串中出现的位置,从字符串末尾算起。
    'Check if the Directory exists or not
    'Parameter:in_DirectoryName
    'return :verifyDirectoryExist
    Function verifyDirectoryExist(in_DirectoryName As String)
        Dim bln_rtValue As Boolean 'the result of Directory is exist or not
        Dim str_fileName As String 'the file name
        Dim str_filepath As String 'the file path
           
        If Dir(in_DirectoryName) <> "" Then
            str_fileName = Dir(in_DirectoryName)
        Else
            str_fileName = Mid(in_DirectoryName, InStrRev(in_DirectoryName, "") + 1)   '根据文件全路径名找文件名字。
        End If
        str_filepath = Replace(in_DirectoryName, str_fileName, "")
       
        If Dir(str_filepath, 16) <> Empty Then   '验证路径是否存在
            bln_rtValue = True
        Else
            bln_rtValue = False
        End If
        verifyDirectoryExist = bln_rtValue
    End Function

    '33--获取文件名的后缀名 instrrev()函数的使用
    Sub test()
        Dim str As String
        Dim str_tz As String
        str = "ab.cdef.csv"
       
        str_tz = VBA.Right(str, Len(str) - InStrRev(str, "."))
        Debug.Print Len(str)  ' 11
        Debug.Print InStrRev(str, ".")  ' 8
        Debug.Print str_tz
        Debug.Print InStr(str, ".")  ' 3
    End Sub
    '34--清空某列:
    Sub clearcontents()
        ThisWorkbook.Sheets(1).Range("F2:F65535").clearcontents '清空F列
        ThisWorkbook.Sheets(1).Range("F2:F65535").Font.Color = vbBlack  '设置某列字体为黑色
    End Sub
    '35--获取数据起始行
    'get start_row of data in specified column in specified sheet.
    'eg: the header's row  in B column is 5, generally the data start_row is 5+1=6.
    'arguments: worksheet,column,header_name.
    'added by collin 2019-09-10.
    '本例可以使用find()函数重写,速度更快。
    Function getDataStartRow(in_ws As Worksheet, in_col As String, in_header As String)
        Dim rng As Range
        Dim usedrow As Long
        usedrow = getLastValidRow(in_ws, in_col)
        getDataStartRow = 0
       
        For Each rng In in_ws.Range(in_col & 1, in_col & usedrow)
            If unifiedFormat(rng.Value) = unifiedFormat(in_header) Then
                getDataStartRow = rng.Row + 1
                Exit Function
            End If
        Next
       
        getDataStartRow = 0
    End Function
    '36--获取某列的最后一行(有数据的最后一行)
    'Get last row of Column N in a Worksheet
    Function getLastValidRow(in_ws As Worksheet, in_col As String)
        getLastValidRow = in_ws.Cells(in_ws.Rows.count, in_col).End(xlUp).Row
    End Function
    '37--格式化字符串
    Function unifiedFormat(in_str As String)
        Dim str As String
        str = in_str
        str = UCase(str)
        str = Replace(str, " ", "")
        str = Replace(str, Chr(10), "") 'remove change line
        str = Replace(str, "_", "")
        str = Replace(str, "-", "")
        str = Replace(str, "–", "")
        str = Replace(str, ";", "")
        str = Replace(str, "(", "")
        str = Replace(str, ")", "")
        str = Replace(str, "%", "")
        str = Replace(str, ".", "")
        str = Replace(str, "/", "")
        unifiedFormat = str
    End Function

    '38--利用字典对指定列去重(不改变原列,将去重后的值存入到字典的keys中)
    'get unique value from Duplicate Values in specified sheet and column,and save those unique values into Arrary.
    'argus: worksheet, column, header, arrary(which must be defined as variant styte before passing it into this function)
    Function saveUniqueValueIntoArrFromDuplicateValues(in_ws As Worksheet, in_col As String, in_header As String, ByRef in_arr_variant As Variant)
        Dim d As Object
        Dim i As Long
        Dim s As String
        Dim usedrow As Long
        Dim rng As Range
        Dim int_startrow As Integer
       
        int_startrow = getDataStartRow(in_ws, in_col, in_header)
        usedrow = getLastValidRow(in_ws, in_col)
       
        Set dic = CreateObject("scripting.dictionary")
       
        For Each rng In in_ws.Range(in_col & int_startrow, in_col & usedrow)
            s = rng.Value
            If Not d.Exists(s) Then
                dic(s) = ""     '设字典的value 为""
            End If
        Next rng
        in_arr_variant = dic.keys
    End Function
    Sub test2()
        Dim ar As Variant
        'Dim ar(1 To 14) As String
       
        'For i = 1 To 14
        '  arr(i) = ThisWorkbook.Worksheets(2).Range("A" & i).Value
        'Next i
        Call saveUniqueValueIntoArrFromDuplicateValues(ThisWorkbook.Worksheets(2), "A", "header", ar)
        ThisWorkbook.Worksheets(2).Range("B1:B" & UBound(ar) + 1) = Application.WorksheetFunction.Transpose(ar)
    End Sub
    Sub test3()
        Dim rng As Range
       
        For Each rng In ThisWorkbook.Worksheets(2).Range("D1:D14")
            Debug.Print rng
        Next
    End Sub
    '39--数字转列号字母
    'Convert number to column
    Function convertnumbertocolumn(ByVal num As Long) As String
        convertnumbertocolumn = Replace(Cells(1, num).Address(False, False), "1", "")
    End Function
    '40--列号字母转数字
    'Convert column to number
    Function convertcolumntonumber(ByVal col As String) As Long
        convertcolumntonumber = Range("a1:" & col & "1").Cells.count
    End Function
    '41--筛选和筛选后复制
    '使用aupayroll tax里的一段代码示例:完整代码请找aupayroll tax parm file.
    Sub PreApro11()
            If ws_apro_input.AutoFilterMode = True Then
                ws_apro_input.AutoFilterMode = False
            End If
            ws_apro_input.Range("$A$3:$AF$" & int_last_row_input).AutoFilter Field:=2, Criteria1:=str_filter, Operator:=xlFilterValues
           
            'use range.SpecialCells(xlCellTypeVisible).Copy to copy filtered range.
            ws_apro_input.Range("A1:AF" & int_last_row_input).SpecialCells(xlCellTypeVisible).Copy ws_new_apro.Range("A1")
           
            ws_new_apro.Cells.WrapText = False
            ws_new_apro.Columns("A:AF").AutoFit
           
            ws_new_apro.Name = ws_apro_input.Name
            If verifyFileExist(get_F30_Apro_Filter_File) Then
                Kill get_F30_Apro_Filter_File
            End If
            wb_new_apro.SaveAs Filename:=get_F30_Apro_Filter_File
           
            closeF2_Apro_File False
            wb_new_apro.Close savechanges:=True
        End If
    End Sub

    '42-1-将指定两列分别作为Key和Value添加到字典中
    'this funtion is designed to add AwardType and RSUorSO in 'Misc_Config' sheet to dictionary.
    'key: AwardType
    'value: RSUorSO
    Private Function addAwardType_RSUorSOToDictionary()
        Dim ws_misc             As Worksheet
        Dim index               As Integer
        Dim str_awardType       As String
        Dim str_RSUorSO         As String
       
        Set dic_awardType_RSUorSO = CreateObject("Scripting.Dictionary")
        Set ws_misc = ThisWorkbook.Sheets(STR_Sheet_Misc_Config)
       
        For index = 3 To getLastValidRow(ws_misc, "J")        '从第3行开始是有效数据
       
            str_awardType = VBA.Trim(ws_misc.Range("J" & index))  'key
            str_RSUorSO = VBA.Trim(ws_misc.Range("K" & index))    'value
       
            If Not dic_awardType_RSUorSO.Exists(str_awardType) Then     '判断key是否已经存在,不存在才添加
                dic_awardType_RSUorSO.Add str_awardType, str_RSUorSO
            End If
       
        Next index
    End Function
    '42-2-将指定三列的一列作为Key和两外两列作为Value添加到字典中
    Private Function addIT0001ToDictionary()
        Dim ws_it0001           As Worksheet
        Dim index_it0001        As Long
        Dim arr()
       
        Dim str_global_id       As String
        Dim str_company_code    As String
        Dim str_Personnel_Area  As String
       
        openF20_IT0001_Report
        Set ws_it0001 = wb_F20_IT0001_Report.Sheets(1)
       
        Set dic_it0001 = CreateObject("Scripting.Dictionary")
        For index_it0001 = 2 To getLastValidRow(ws_it0001, F20_Col_IBMCNUM)
           
            str_global_id = add0IfEELess9(VBA.Trim(ws_it0001.Range(F20_Col_IBMCNUM & index_it0001)))  'key
            str_company_code = VBA.Trim(ws_it0001.Range(F20_Col_CompanyCode & index_it0001))          'value 数组的第一个元素
            str_Personnel_Area = VBA.Trim(ws_it0001.Range(F20_Col_PersonnelArea & index_it0001))      'value 数组的第二个元素
           
            If str_global_id <> "" And Not dic_it0001.Exists(str_global_id) Then
                arr = Array(str_company_code, str_Personnel_Area)                    '使用Array(元素1,元素2,...) 函数定义数组
                dic_it0001.Add str_global_id, arr
            End If
               
        Next index_it0001
       
    End Function

    '43--loop files in specified folder
    'this function is designed to judge whether those files in workercomp folder could be calculated or not.if any file couldn't be calculated,returns false.
    Private Function isAllFilesCalculable() As Boolean
        Dim str_targetfilename                                As String
        Dim str_targetfilefullname                            As String
        Dim wsht                                              As Worksheet
        Dim rng                                               As Range
        Dim usedrows                                          As Byte
        Dim str_thefirstcnum                                  As String
        Dim bo_headerinsheet                                  As Boolean
        Dim bo_snconsistent                                   As Boolean
        My_Err = "WorkersCompCalculation module error - isAllFilesCalculable function error."
       
        bo_snconsistent = True
        isAllFilesCalculable = True
        bo_headerinsheet = False
        long_calculablefilecount = 0
       
        str_reportingmonthinparm = unifiedFormat("Reporting Month" & ThisWorkbook.Worksheets(STR_AU_PayrollTax_Parm).Range(Col_AU_PayrollTax_Parm_Value & 3) & "/" & ThisWorkbook.Worksheets(STR_AU_PayrollTax_Parm).Range(Col_AU_PayrollTax_Parm_Value & 4))
       
        '1--Useing  'Do...Loop'  to make sure there are no uncalculable files in this folder, if any(any file's ,any erroType),exit function and  return isAllFilesCalculable False.
        'it is no need to judge wether there are files in this folder,cause the judgement has been done in 'Invalidate' part.
        On Error GoTo 0
        str_targetfilename = Dir(get_F14_Worker_Comp_Folder() & "*.xlsx")
       
        Do
           boolean_calculateFlag = False
           str_thefirstcnum = "null"
           str_targetfilefullname = get_F14_Worker_Comp_Folder() & str_targetfilename
           Set wb_workercomp = checkAndAttachWorkbook(str_targetfilefullname)
          
           'restore the  arr_reportmonthsheets() after circle of  one file.This array is used to store reportMonthSheet's name, and the function 'updateErrorDetails' will use it,when the error message relevent to those sheets.
           byte_reportmonthsheetscount = 0
           ReDim arr_reportmonthsheets(1 To byte_reportmonthsheetscount + 1)
           
           For Each wsht In wb_workercomp.Worksheets
                '2--get the reportingMonth of this worksheet, if "Reporting Month"exist,give it's value to reportingMonth ,otherwise reportingMonth equals to "".
                str_reportingmonth = "null"
                str_cnum = "null"
                usedrows = wsht.Range("A" & Rows.count).End(xlUp).Row
                For Each rng In wsht.Range("A1", "A" & usedrows)
                    If unifiedFormat(rng.Value) Like unifiedFormat("Reporting Month*") Then
                        str_reportingmonth = unifiedFormat(rng.Value)
                        Exit For
                    End If
                Next rng
               
                'step 3--if reportingMonth in this worksheet matches the str_reportingmonthinparm, then judge cnum and header
                'step 4--judge whether the CNUM exist and be consistent with all reporting month sheets in this workbook.
                If str_reportingmonth = str_reportingmonthinparm Then
                    'if reportingMonth = str_reportingmonthinparm ,then add this worksheet's name to arry, the function 'updateErrorDetails' will use it,when the cnums are inconsistent with each other.
                    byte_reportmonthsheetscount = byte_reportmonthsheetscount + 1
                    ReDim Preserve arr_reportmonthsheets(1 To byte_reportmonthsheetscount)
                    arr_reportmonthsheets(byte_reportmonthsheetscount) = wsht.Name
                   
                    'get cnum in this reporting month sheet.
                    For Each rng In wsht.Range("A1", "A" & usedrows)
                        If Left(unifiedFormat(rng.Value), 2) = "SN" Then
                            str_cnum = add0IfEELess9(LTrim(Right(Trim(wsht.Range("A2").Value), Len(Trim(wsht.Range("A2").Value)) - 2)))
                            If str_thefirstcnum = "null" Then
                                str_thefirstcnum = str_cnum
                            End If
                            Exit For
                        End If
                    Next rng
                    'if the cnum still equls to "", feedback error message to control report,and skip.
                    If str_cnum = "null" Then
                        isAllFilesCalculable = False
                        Set ws_workercomp = wsht
                        str_errorType = "no cnum found in reporting month sheet"
                        Call updateErrorDetails
                        Exit Function
                    End If
                        'note: use else and if respectively not elseif ,they are definite defierent!
                    If str_cnum <> str_thefirstcnum Then
                        str_errorType = "CNUM is not consistent in reporting month sheets"
                        Call updateErrorDetails
                        isAllFilesCalculable = False
                        Exit Function
                    End If
           
                   ' step 5--if ReportMonthMatched and cnum is ok, then judge the header (whether the header in reporting month sheet match the header in 'Input_Header_Config' sheet of parm file).
                   bo_headerinsheet = isHeaderInWorkerComp(wsht)
                   If bo_headerinsheet Then  'it means the current reporting month sheets is calculable, so add it to arr_calculablefiles.
                        boolean_calculateFlag = True 'it means the current file has at least one matched reporting month sheet and it's header,cnum are ok. the current file is calculable.
                    Else
                        isAllFilesCalculable = False
                        Set ws_workercomp = wsht
                        str_errorType = "no matched header in sheet"
                        Call updateErrorDetails
                        Exit Function
                   End If
              End If
           Next wsht
        
           If boolean_calculateFlag Then
               long_calculablefilecount = long_calculablefilecount + 1
               ReDim Preserve arr_calculablefiles(1 To long_calculablefilecount) As String
               arr_calculablefiles(long_calculablefilecount) = str_targetfilefullname
           End If
            
          'step 6 if boolean_calculateFlag = False, it means that the current file is uncalculable,and there is no need to judge other files,return isAllFileCalculable false, exit this function, skip this part!
           If boolean_calculateFlag = False Then
                isAllFilesCalculable = False
                If str_reportingmonth <> str_reportingmonthinparm Then
                    str_errorType = "no matched sheet in file"
                    Call updateErrorDetails
                End If
                Exit Function
           End If
          
           wb_workercomp.Close savechanges:=False
           Set wb_workercomp = Nothing
           On Error GoTo 0
           str_targetfilename = Dir
           If str_targetfilename = "" Then
               Exit Function
           End If
        
       Loop
      
    End Function
    '44-1--使用一维数组对单元格赋值
    '把1-2000的自然数写入到A1:A2000单元格里
    Function input_test(in_ws As Worksheet)
        Dim i As Long
        Dim arr(1 To 2000) As Long                                                    '关键的语法:定义一维数组
        For i = 1 To 2000
          arr(i) = i
        Next
       
        in_ws.Range("A1:A2000").Value = Application.WorksheetFunction.Transpose(arr)  '关键的语法
           
    End Function
    '44-2--使用二维数组对单元格赋值
    '把1-2000的自然数写入到A1:A2000单元格里
    Function input_test2(in_ws As Worksheet)
        Dim i As Long
        Dim arr(1 To 2000, 1 To 1) As Long       '关键的语法:定义二维数组
        For i = 1 To 2000
          arr(i, 1) = i
        Next
       
        in_ws.Range("A1:A2000").Value = arr      '关键的语法
           
    End Function

    '45--使用find()函数来查找第一次出现的字符串,代替for each 循环
    Function test_find(in_ws As Worksheet, in_str As String, in_setpath As String)
        '代码片段:
        Dim rng As Range
        Set rng = ws.Cells.Find(in_str, , , 1)
        rng.Offset(0, 1).Value = in_setpath
    End Function
     
    '46--获取环境变量的方式1 VBA.Environ(name):
    Private Function get_env()
       str_rpa_environment = VBA.Environ("RPA_ENVIRONMENT")
    End Function
    '47--读取环境变量的方法2--readUserEnv(name)
    Function readUserEnv(in_name As String)
        Dim objUserEnvVars As Object
        Dim strVar As String
       
        Set objUserEnvVars = CreateObject("WScript.Shell").Environment("User")
        strVar = objUserEnvVars.Item(in_name)
    '    Debug.Print strVar
        readUserEnv = strVar
    End Function
    '48--对合并了的单元格的查找
    'Robot needs to base on reporting month in parm file, search AU payroll calendar by month column in “QM&QF Calendar” in parm file, to find all pay period in the month.
    Private Function Validate_Payroll_Calendar(Col_Month As String, Col_PayPeriod As String, PayType As String) As Boolean
        Dim sht_PayrollCalendar                 As Worksheet
        Dim Calendar_Date                       As Date
        Dim Month_LastRow                       As Long
        Dim PayPeriod_LastRow                   As Long
        Dim index                               As Long
        Dim count                               As Long
        Dim Q_index                             As Long
        Dim Q_count                             As Long
        Dim PayPeriod                           As String
        Dim Calendar_PayPeriod                  As String
     
        My_Err = "ESPPCaliculation module error - Validate_Payroll_Calendar function error."
     
        Validate_Payroll_Calendar = True
        Calendar_PayPeriod = ""
        Set sht_PayrollCalendar = ThisWorkbook.Sheets(Sht_PayrollCalendar_Name)
        Month_LastRow = getLastValidRow(sht_PayrollCalendar, Col_Month)
        PayPeriod_LastRow = getLastValidRow(sht_PayrollCalendar, Col_PayPeriod)
        count = Application.Max(Month_LastRow, PayPeriod_LastRow)
        For index = 3 To count
            If Trim(sht_PayrollCalendar.Range(Col_Month & index)) <> "" Then
                Calendar_Date = CDate(Trim(sht_PayrollCalendar.Range(Col_Month & index)))
                If Year(Calendar_Date) = get_Reporting_Year And Month(Calendar_Date) = Val(get_Reporting_Month) Then   '根据reporting year & month 找对应的月的 QM QF 的period
                    If sht_PayrollCalendar.Range(Col_Month & index).MergeCells Then   '如果日期的单元格合并了
                        'MergeArea.Rows.count 被合并的单元格的个数。比如第10行是一个合并单元格的开始行,公合并了3个单元格,那么 3+10-1=12,表示10,11,12行被合并
                        Q_count = sht_PayrollCalendar.Range(Col_Month & index).MergeArea.Rows.count + index - 1
                        For Q_index = index To Q_count '遍历 period列的10,11,12行
                            PayPeriod = Replace(sht_PayrollCalendar.Range(Col_PayPeriod & Q_index), " ", "")
                            If PayPeriod <> "" Then
                                If Calendar_PayPeriod <> "" Then
                                    Calendar_PayPeriod = Calendar_PayPeriod & "/" & PayType & " " & PayPeriod '对于第一次 For Q_index循环:QM/PP04
                                Else
                                    Calendar_PayPeriod = PayType & " " & PayPeriod   'Calendar_PayPeriod 最终能得到类似:QM PP04   或 QF PP07/QF PP08/QF PP09
                                End If
                            End If
                        Next Q_index
                        Exit For
                    End If
                End If
            End If
        Next index
        If Calendar_PayPeriod = "" Then
            Validate_Payroll_Calendar = False
        End If
        If Calendar_PayPeriod_List <> "" Then
            'Calendar_PayPeriod_List 最终能得到类似:QM PP04/QF PP07/QF PP08/QF PP09(此function会先后调用两次:Validate_Payroll_Calendar("A","B","QM"),Validate_Payroll_Calendar("D","E","QF"))
            Calendar_PayPeriod_List = Calendar_PayPeriod_List & "/" & Calendar_PayPeriod
        Else
            Calendar_PayPeriod_List = Calendar_PayPeriod
        End If
      
    End Function
     
     
     
     
  • 相关阅读:
    python---对齐
    python---保留两位小数
    调试--valgrind
    调试--gdb远程调试
    调试---将断点设置在某个文件的某行(多线程调试有用)
    调试-----调试正在运行的多线程程序
    调试---调试正在运行的程序
    linux----dmesg 时间
    c++----static 重复调用
    调试--汇编调试
  • 原文地址:https://www.cnblogs.com/Collin-pxy/p/13039167.html
Copyright © 2020-2023  润新知