【问题标题】:Reference a cell if the sheet contains a certain string using VBA如果工作表包含使用 VBA 的某个字符串,则引用一个单元格
【发布时间】:2016-08-05 07:22:08
【问题描述】:

下面的代码在我的活动工作表中复制“ADXL364”表,但是如果它包含“XL364”或“364”,我可以复制该表

如果我把星号 'C:\data[adxl364.xls]*ADXL364_QC'!A1 在我的代码中它不起作用。

Sub GetRange()
    With Range("A:Z")
        .Formula = "=If('C:\data\[adxl364.xls]ADXL364_QC'!A1 > 0,'C:\data\[adxl364.xls]ADXL364_QC'!A1,Text(,))"
        .Formula = .Value
    End With
    End Sub

长代码将从用户那里获取文件的位置,然后复制包含 ADXL364XL364

的工作表
With ActiveWorkbook
    Sheets.Add.Name = "Flow_table"
    Application.EnableEvents = False

    TP_location = Left(TextBox1.Value, InStrRev(TextBox1.Value, "\"))
    TP_filename = Right(TextBox1.Value, Len(TextBox1.Value) - InStrRev(TextBox1.Value, "\"))
    TP_filename = "[" & TP_filename & "]"
    TP_formula = "'" & TP_location & TP_filename & TextBox2.Value & "'!A1"

    getcellvalue = "=if(" & TP_formula & ">0," & TP_formula & "," & """"")"

        With Range("A:Z")
        .Formula = getcellvalue
        .Formula = .Value
        End With

    Sheets.Add.Name = "Job_lists"

End With
Unload UserForm2
End Sub

【问题讨论】:

  • 复制发生在哪里?
  • 对于单元格 A1,写入该单元格的公式为 =If('C:\data[adxl364.xls]ADXL364_QC'!A1 > 0,'C:\data[adxl364.xls]ADXL364_QC '!A1,"")。循环发生在从 A 到 Z。所以也许正确的术语是从封闭的工作簿中引用一个单元格
  • 您可以尝试编辑路径位置并选择要“引用”的工作表并将模块粘贴到新工作表中。它会给你一份参考表的副本。在这种情况下,ADXL364 表,范围 A 到 Z
  • 你知道你可以在没有 VBA 的情况下解决这个问题吗?在单元格中计算您想要的公式(作为字符串),然后在该单元格上使用INDIRECT()
  • @iDevlop 这很酷。但是,它需要 VBA,因为文件和工作表的位置是动态的。这是完整的代码。

标签: vba excel copy


【解决方案1】:

一种丑陋但可能的方法是使用蛮力错误捕获技术。

但是,更优雅的解决方案可能是使用 ADO。例如,您可以运行两个“查询”:第一个在表模式上,它将在指定文件中为您提供工作表名称,第二个在找到的工作表名称上。这将产生一个RecordSet,其中包含您关闭的工作表的数据,可以使用.CopyFromRecordset 方法将其直接写入Range。当然,您可以只运行第一个查询来找到您的工作表名称,然后像您在发布的代码中一样继续前进。

下面的示例显示了两个查询的代码。这一切都是后期绑定,所以你不需要参考 ADO 库,但我会把这个决定留给你。我在模块顶部放置了一些常量,这些常量可能需要根据您拥有的 Excel 版本进行更改。您还需要编写自己的错误处理程序(尤其是关闭连接),但我还是把那个留给您。

Option Explicit
Private Const SCHEMA_TABLES As Integer = 20
Private Const OPEN_FORWARD_ONLY As Integer = 0
Private Const LOCK_READ_ONLY As Integer = 1
Private Const CMD_TEXT As Long = 1
Private Const PROVIDER As String = "Microsoft.ACE.OLEDB.12.0"
Private Const XL_PROP As String = """Excel 12.0;HDR=No"""
Private Const SHEETS_FIELD_NAME As String = "TABLE_NAME"

Public Sub AcquireData()
    Dim fPath As String
    Dim fName As String
    Dim key As String
    Dim addr As String
    Dim oConn As Object
    Dim oRS As Object
    Dim connString As String
    Dim sql As String
    Dim found As Boolean
    Dim sheetField As String

    'Define the path and file name
    fPath = "C:\Users\User\Documents\StackOverflow"
    fName = "closed_book.xlsx"

    'Define the search key
    key = "XL364"

    'Define the address of closed worksheet
    'If reading one cell then use [address:address], eg "A1:A1"
    addr = "A1:E5"

    'Late bind the ADO objects
    Set oConn = CreateObject("ADODB.Connection")
    Set oRS = CreateObject("ADODB.Recordset")

    'Open conection
    connString = "Provider=" & PROVIDER & ";" & _
                 "Data Source=" & fPath & "\" & fName & ";" & _
                 "Extended Properties=" & XL_PROP & ";"

    oConn.Open connString

    'Search for the sheet name containing your key
    'in the tables (ie sheets) schema
    found = False
    oRS.Open oConn.OpenSchema(SCHEMA_TABLES)
    Do While Not oRS.EOF
        sheetField = oRS.Fields(SHEETS_FIELD_NAME).Value
        If InStr(sheetField, key) > 0 Then
            found = True
            Exit Do
        End If
        oRS.MoveNext
    Loop
    oRS.Close

    'Read the target data
    If found Then
        sql = "SELECT * FROM [" & _
              sheetField & addr & "];"

        oRS.Open sql, oConn, OPEN_FORWARD_ONLY, LOCK_READ_ONLY, CMD_TEXT

        'Write the data to your worksheet
        If Not oRS.EOF Then
            ThisWorkbook.Worksheets("Sheet1").Range("A1") _
                .CopyFromRecordset oRS
        End If

    End If


    'Housekeeping
    oRS.Close
    Set oRS = Nothing
    oConn.Close
    Set oConn = Nothing

End Sub

【讨论】:

    【解决方案2】:

    您可以通过循环遍历每个工作表并使用InStr(字符串中)函数来测试工作表名称中是否包含文本“XL364”。例如:

    For Each ws in Workbooks.Open(filepathStringFromUserInput)
        If InStr(1, ws.Name, "XL364") > 0 Then
            MsgBox "hi"
            'Set hwSheet = ws
        End If
    Next ws
    
    
    With hwSheet
        'do some code eg:
        .Range("A1").Value = "Hi"
    End With
    

    【讨论】:

    • 你好@Oliver Carr,ADXL364.xls 是一个封闭的工作簿。所以我认为代码行不通。
    • @J_Gonzales 我认为没有办法以您正在寻找的方式引用工作表。尝试我编辑的答案以打开指定的文件并遍历其工作表以查找。
    猜你喜欢
    • 2022-10-01
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多