簡體   English   中英

VBA - 如果單元格包含某個值而不是等於或不等於,則復制值

[英]VBA - Copy value if cell CONTAINS certain value rather than equal to or not equal to

我有一個工作宏,循環文件夾打開文件,從名稱“HOLDER”和“CUTTING TOOL”的列中獲取重要信息,並將所有信息打印到一個excel文檔,masterfile。

我遇到的問題是,在“HOLDER”欄中,有時會有“Holder / Toolbox”這樣的額外信息,但它並不一致。 我讓它與“HOLDER”一起工作,但我想知道是否仍然可以這樣做,無論HOLDER標題名稱中是否有額外的文本,或者它是小寫而不是所有大寫。 感謝您提供任何幫助!

這是處理“HOLDER”部分的代碼。 下面是完整的代碼以便更好地參考(第4節關於我正在修改的部分,第8部分是它引用的功能)。

'find the headers on the sheet
Set hc1 = HeaderCell(StartSht.Range("B1"), "HOLDER")

...

'(4)
            'find HOLDER on the source sheet
            Set hc3 = HeaderCell(ws.Cells(ROW_HEADER, 1), "HOLDER")
            If Not hc3 Is Nothing Then

                Set dict = GetValues(hc3.Offset(1, 0))
                If dict.count > 0 Then
                    Set d = StartSht.Cells(Rows.count, hc1.Column).End(xlUp).Offset(1, 0)
                    'add the values to the master list, column 2
                    d.Resize(dict.count, 1).Value = Application.Transpose(dict.items)
                End If
            Else
                'header not found on source worksheet
            End If

...

'(8)
'get all unique column values starting at cell c
Function GetValues(ch As Range, Optional vSplit As Variant) As Object
    Dim dict As Object
    Dim rng As Range, c As Range
    Dim v
    Dim spl As Variant

    Set dict = CreateObject("scripting.dictionary")

    For Each c In ch.Parent.Range(ch, ch.Parent.Cells(Rows.count, ch.Column).End(xlUp)).Cells
        v = Trim(c.Value)
        If Len(v) > 0 And Not dict.exists(v) Then

            If Not IsMissing(vSplit) Then
            spl = Split(v, ";")

            v = spl(0)
            End If

            If Not IsMissing(vSplit) Then
            spl = Split(v, ",")

            v = spl(0)
            End If
            dict.Add c.Address, v
        End If
    Next c
    Set GetValues = dict
End Function

完整的代碼

Option Explicit

Sub LoopThroughDirectory()

    Const ROW_HEADER As Long = 10

    Dim objFSO As Object
    Dim objFolder As Object
    Dim objFile As Object
    Dim MyFolder As String
    Dim StartSht As Worksheet, ws As Worksheet
    Dim WB As Workbook
    Dim i As Integer
    Dim LastRow As Integer, erow As Integer
    Dim Height As Integer
    Dim RowLast As Long
    Dim f As String
    Dim dict As Object
    Dim hc As Range, hc1 As Range, hc2 As Range, hc3 As Range, d As Range

    Set StartSht = Workbooks("masterfile.xlsm").Sheets("Sheet1")

    'turn screen updating off - makes program faster
    Application.ScreenUpdating = False

    'location of the folder in which the desired TDS files are
    MyFolder = "C:\Users\trembos\Documents\TDS\progress\"

    'find the headers on the sheet
    Set hc1 = HeaderCell(StartSht.Range("B1"), "HOLDER")
    Set hc2 = HeaderCell(StartSht.Range("C1"), "CUTTING TOOL")

    'create an instance of the FileSystemObject
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    'get the folder object
    Set objFolder = objFSO.GetFolder(MyFolder)
    i = 2


    'loop through directory file and print names
'(1)
    For Each objFile In objFolder.Files
        If LCase(Right(objFile.Name, 3)) = "xls" Or LCase(Left(Right(objFile.Name, 4), 3)) = "xls" Then
'(2)
            'Open folder and file name, do not update links
            Set WB = Workbooks.Open(fileName:=MyFolder & objFile.Name, UpdateLinks:=0)
            Set ws = WB.ActiveSheet
'(3)
                'find CUTTING TOOL on the source sheet
                Set hc = HeaderCell(ws.Cells(ROW_HEADER, 1), "CUTTING TOOL")
                If Not hc Is Nothing Then

                    Set dict = GetValues(hc.Offset(1, 0), "SplitMe")
                    If dict.count > 0 Then
                        Set d = StartSht.Cells(Rows.count, hc2.Column).End(xlUp).Offset(1, 0)
                        'add the values to the master list, column 3
                        d.Resize(dict.count, 1).Value = Application.Transpose(dict.items)
                    End If
                Else
                    'header not found on source worksheet
                End If
'(4)
                'find HOLDER on the source sheet
                Set hc3 = HeaderCell(ws.Cells(ROW_HEADER, 1), "HOLDER")
                If Not hc3 Is Nothing Then

                    Set dict = GetValues(hc3.Offset(1, 0))
                    If dict.count > 0 Then
                        Set d = StartSht.Cells(Rows.count, hc1.Column).End(xlUp).Offset(1, 0)
                        'add the values to the master list, column 2
                        d.Resize(dict.count, 1).Value = Application.Transpose(dict.items)
                    End If
                Else
                    'header not found on source worksheet
                End If
'(5)
            'print filename and TDS information
            With WB
                For Each ws In .Worksheets
                        'print the file name to Column 1
                        StartSht.Cells(i, 1) = objFile.Name
                        StartSht.Cells((GetLastRowInColumn(StartSht, "C")), 1) = objFile.Name

                        'print TDS name from J1 cell to Column 4
                        With ws
                            .Range("J1").Copy StartSht.Cells(i, 4)
                        End With
                        i = GetLastRowInSheet(StartSht) + 1
                'move to next file
                Next ws
'(6)
                'close, do not save any changes to the opened files
                .Close SaveChanges:=False
            End With
        End If
    'move to next file
    Next objFile
    'turn screen updating back on
    Application.ScreenUpdating = True
    ActiveWindow.ScrollRow = 1
'(7)
End Sub

'(8)
'get all unique column values starting at cell c
Function GetValues(ch As Range, Optional vSplit As Variant) As Object
    Dim dict As Object
    Dim rng As Range, c As Range
    Dim v
    Dim spl As Variant

    Set dict = CreateObject("scripting.dictionary")

    For Each c In ch.Parent.Range(ch, ch.Parent.Cells(Rows.count, ch.Column).End(xlUp)).Cells
        v = Trim(c.Value)
        If Len(v) > 0 And Not dict.exists(v) Then

            If Not IsMissing(vSplit) Then
            spl = Split(v, ";")

            v = spl(0)
            End If

            If Not IsMissing(vSplit) Then
            spl = Split(v, ",")

            v = spl(0)
            End If
            dict.Add c.Address, v
        End If
    Next c
    Set GetValues = dict
End Function

'(9)
'find a header on a row: returns Nothing if not found
Function HeaderCell(rng As Range, sHeader As String) As Range
    Dim rv As Range, c As Range
    For Each c In rng.Parent.Range(rng, rng.Parent.Cells(rng.Row, Columns.count).End(xlToLeft)).Cells
        If Trim(c.Value) = sHeader Then
            Set rv = c
            Exit For
        End If
    Next c
    Set HeaderCell = rv
End Function

'(10)
Function GetLastRowInColumn(theWorksheet As Worksheet, col As String)
    With theWorksheet
        GetLastRowInColumn = .Range(col & .Rows.count).End(xlUp).Row
    End With
End Function


'(11)
Function GetLastRowInSheet(theWorksheet As Worksheet)
Dim ret
    With theWorksheet
        If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
            ret = .Cells.Find(What:="*", _
                          After:=.Range("A1"), _
                          Lookat:=xlPart, _
                          LookIn:=xlFormulas, _
                          SearchOrder:=xlByRows, _
                          SearchDirection:=xlPrevious, _
                          MatchCase:=False).Row
        Else
            ret = 1
        End If
    End With
    GetLastRowInSheet = ret
End Function

好吧, InStr有助於找出字符串中是否包含子字符串。 基本上,它返回的是字符串中子字符串的位置; 所以,一行如下:

Instr ("hello world!", "h")

將返回1第一個參數是您要查看的字符串,第二個參數是您要查找的子字符串。

因此,如果返回值不為零,則表示包含子字符串。 你會這樣檢查:

If InStr(string, substring) <> 0 then
'do code
End If

此外,對於區分大小寫的方案:

您可能希望將單元格值放入字符串變量中,但轉換為大寫字母; 然后檢查“HOLDER”等等。 這不會改變單元格中的值,只是為了比較。 做就是了:

dim uString as String

uString = UCase(c.Value)

需要調整的部分是搜索標題行,比較值的部分。 看起來這是在HeaderCell函數中。 看起來比較的具體線是:

If Trim(c.Value) = sHeader Then

這是將標題行中每個單元格的內容與傳入的值(在您的情況下為sHeader =“Holder”)進行比較。

你最好做一個測試,看看sHeader是否在單元格值中,不等於單元格值。 InStr功能非常適合這種情況。 (未經測試的航空代碼):

If InStr(c.Value, sHeader) <> 0 Then

這將搜索標題行中每個單元格的內容,以查看傳遞給sHeader的值是否在值的任何位置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM