Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在VBA中使用ListObject列名_Vba_Excel - Fatal编程技术网

在VBA中使用ListObject列名

在VBA中使用ListObject列名,vba,excel,Vba,Excel,当工作表更改时,我需要执行一些VBA代码。对于这一点,我有一个If-then-else的情况 在任何特定行中(我有可变数量的行(即行项目)): 在工作表更改事件中,我使用ActiveSheet.Protect和解锁/锁定。使用范围内的密码取消保护 我现在正试图弄清楚如何做到这一点。具体来说,如何使用列名-如公式中的列名?==for Excel 2007+=== 如果您使用的是Excel2007+,我建议您使用ListObject、ListColumns和ListRows(研究对象模型) 我的方法

当工作表更改时,我需要执行一些VBA代码。对于这一点,我有一个If-then-else的情况

在任何特定行中(我有可变数量的行(即行项目)):

在工作表更改事件中,我使用
ActiveSheet.Protect
解锁/锁定。使用范围内的密码取消保护


我现在正试图弄清楚如何做到这一点。具体来说,如何使用列名-如公式中的列名?

==for Excel 2007+===

如果您使用的是Excel2007+,我建议您使用ListObject、ListColumns和ListRows(研究对象模型)

我的方法背后的理念:

  • 表单、数据和报告应始终分开,因此

  • 将您的所有数据收集到一个表中,在一个专用的工作表中。选择数据并按Ctrl+(T或L)。确保每张工作表只有一个数据表

  • 使用表,您将能够使用ListObject、ListColumns和ListRows对象

  • 这是完整的代码

    Public Sub test()
        IntersectColumnRows ActiveSheet, "", "Type", "Amount", Range("A1"), Range("B1"), Range("C1")
    End Sub
    
    Public Sub IntersectColumnRows(currentSheet As Worksheet, sheetPassword As String, columnTitle_Type As String, columnTitle_Amount As String, rangeA As Range, rangeB As Range, rangeC As Range)
    
        'variable declaration
        Dim listO As ListObject
        Set listO = currentSheet.ListObjects(1)
    
        'Takes care of sheet protection
        Dim isSheetProtected As Boolean
        isSheetProtected = currentSheet.ProtectionMode
        If isSheetProtected Then _
            currentSheet.Unprotect (sheetPassword)
    
        'store your type column
        Dim columnRangeType As Range
        Set columnRangeType = listO.ListColumns(columnTitle_Type).Range
        'store your 2nd column
        Dim columnRangeAmount As Range
        Set columnRangeAmount = listO.ListColumns(columnTitle_Amount).Range
    
        'the actual routine you are asking for
        Dim listR As ListRow
        For Each listR In listO.ListRows
            'intersect the TYPE column with the current row
            Dim typeRangeIntersection As Range
            Set typeRangeIntersection = Application.Intersect(listR.Range, columnRangeType)
            'intersect the AMOUNT column with the current row
            Dim amountRangeIntersection As Range
            Set amountRangeIntersection = Application.Intersect(listR.Range, columnRangeAmount)
    
            'the logic you required
            If typeRangeIntersection.Value = rangeA.Value Then
                amountRangeIntersection.Locked = False
                amountRangeIntersection.Value = rangeB.Value
                amountRangeIntersection.Locked = True
            ElseIf typeRangeIntersection.Value = rangeC.Value Then
                amountRangeIntersection.Locked = False
                amountRangeIntersection.Value = rangeC.Value
                amountRangeIntersection.Locked = True
            Else
                amountRangeIntersection.Locked = False
            End If
         Next
    
        'Cleans up sheet protection
        If isSheetProtected Then _
            currentSheet.Protect (sheetPassword)
    End Sub
    
    以下是“我是怎么做的”:

  • 存储所有必需列的ListColumn.Range(类型、金额)

  • 对于每个列表行的循环

  • 我将ListRow.Range与ListColumn.Range相交

  • 应用你想要的逻辑

  • 在代码之外,研究如何

  • 我在其中包含了保护/密码逻辑,因此如果需要,您可以将其删除

  • 每个变量都有一个非常明确的名称

  • 我没有包含任何硬编码的值,所以它仍然是参数化的,如果您需要为不同的图纸调整一些内容


  • 嗨,安德烈,我会研究一下,让你知道。是的,我忘了提到这是针对Excel 2010的。我不知道你到底在问什么,但要在VBA中像在工作表上一样使用列名,你可以将它与任何其他名称的范围引用相同:范围(“Table1[name]”)返回引用“name”列的范围对象。但是,正如Andre所建议的,您可能应该更仔细地查看ListObject以获得更高效的编码。
    Public Sub test()
        IntersectColumnRows ActiveSheet, "", "Type", "Amount", Range("A1"), Range("B1"), Range("C1")
    End Sub
    
    Public Sub IntersectColumnRows(currentSheet As Worksheet, sheetPassword As String, columnTitle_Type As String, columnTitle_Amount As String, rangeA As Range, rangeB As Range, rangeC As Range)
    
        'variable declaration
        Dim listO As ListObject
        Set listO = currentSheet.ListObjects(1)
    
        'Takes care of sheet protection
        Dim isSheetProtected As Boolean
        isSheetProtected = currentSheet.ProtectionMode
        If isSheetProtected Then _
            currentSheet.Unprotect (sheetPassword)
    
        'store your type column
        Dim columnRangeType As Range
        Set columnRangeType = listO.ListColumns(columnTitle_Type).Range
        'store your 2nd column
        Dim columnRangeAmount As Range
        Set columnRangeAmount = listO.ListColumns(columnTitle_Amount).Range
    
        'the actual routine you are asking for
        Dim listR As ListRow
        For Each listR In listO.ListRows
            'intersect the TYPE column with the current row
            Dim typeRangeIntersection As Range
            Set typeRangeIntersection = Application.Intersect(listR.Range, columnRangeType)
            'intersect the AMOUNT column with the current row
            Dim amountRangeIntersection As Range
            Set amountRangeIntersection = Application.Intersect(listR.Range, columnRangeAmount)
    
            'the logic you required
            If typeRangeIntersection.Value = rangeA.Value Then
                amountRangeIntersection.Locked = False
                amountRangeIntersection.Value = rangeB.Value
                amountRangeIntersection.Locked = True
            ElseIf typeRangeIntersection.Value = rangeC.Value Then
                amountRangeIntersection.Locked = False
                amountRangeIntersection.Value = rangeC.Value
                amountRangeIntersection.Locked = True
            Else
                amountRangeIntersection.Locked = False
            End If
         Next
    
        'Cleans up sheet protection
        If isSheetProtected Then _
            currentSheet.Protect (sheetPassword)
    End Sub