【问题标题】:Find range subset combinations from main range in Excel via VBA通过 VBA 从 Excel 中的主范围中查找范围子集组合
【发布时间】:2020-09-28 15:58:29
【问题描述】:

这里是细节。假设您有 10 X 10 范围的单元格 - A1:J10 可以正常工作。我试图通过 VBA 找到的是,可以从 A1:J10 的主要范围派生多少对包含 5 个单元格和 4 个单元格的非相交范围。例如,A1:A5(5 个细胞子集)和 A6:A9(4 个细胞子集)将是一个有效的对。由于 A1 的范围相交,A1:E5 和 A1:A4 将不是有效对。我主要只是在寻找有效对的数量,但如果有人可以展示如何在工作表上物理列出所有对,那将有所帮助。

提前感谢您的帮助!

【问题讨论】:

  • 每个范围必须是连续的矩形吗?
  • 所以一个范围必须包含 5 个单元格,而另一个必须包含 4 个单元格?除了显而易见的因素外,五没有任何因素,因此只能是 1 X 5 或 5 X 1、4 可以是 1 X 4、4 X 1 或 2 X 2。根据您的特定情况处理这些因素应该不会太糟糕,也许相当多的代码。我认为一般来说要困难得多。
  • 必须用子范围完全填充范围吗?还是您也在寻找未填充的范围?
  • 回想起来,我在示例中打错了字,说明什么不是有效的配对。旨在使用 A1:A5 和 A1:D1 作为无效对的示例。不确定这是否重要,但我想我会澄清一下。
  • 蒂姆-是的。汤姆——是的。邪恶 不知道你在问什么。鉴于 A1:J10 的主要范围,我正在寻找存在多少对不相交的 5 单元格和 4 单元格连续矩形单元格子范围。例如,我知道有 120 个 5 单元格和 140 个 4 个单元格子范围。我就是无法接受参数并制定方程式等,这会给我数字。

标签: excel vba


【解决方案1】:

范围子集组合

Option Explicit

Sub writeRangePairs()
    
    ' Source
    Const wsName As String = "Sheet1"
    Const srcRange = "A1:J10"
    Const RC1 As Long = 5
    Const RC2 As Long = 4
    ' Target
    Const tgtFirstCell As String = "L1"
    ' Other
    Dim wb As Workbook
    Set wb = ThisWorkbook
    
    ' Define Source Range.
    Dim ws As Worksheet
    Set ws = wb.Worksheets(wsName)
    Dim rng As Range
    Set rng = ws.Range(srcRange)
        
    ' Write all possible range addresses
    ' to Source Arrays ('Source1', 'Source2').
    Dim Source1 As Variant
    Source1 = getOneRowOneCol(rng, RC1)
    Dim Source2 As Variant
    Source2 = getOneRowOneCol(rng, RC2)
    
    ' Define Target Array. It is too big,
    ' but It cannot be bigger than UB1 * UB2.
    Dim Target As Variant
    ReDim Target(1 To UBound(Source1) * UBound(Source2), 1 To 3)
    
    Dim i As Long
    Dim k As Long
    Dim m As Long
    
    ' Write values from Source Arrays to Target Array.
    For i = 1 To UBound(Source1)
        For k = 1 To UBound(Source2)
            If Intersect(ws.Range(Source1(i, 1)), ws.Range(Source2(k, 1))) _
              Is Nothing Then
                m = m + 1
                ' Write first range address.
                Target(m, 1) = Source1(i, 1)
                ' Write second range address.
                Target(m, 2) = Source2(k, 1)
                ' Write both addresses as one range address. This column
                ' will contain duplicates which could be removed
                ' by using a dictionary.
                Target(m, 3) = Union(ws.Range(Source1(i, 1)), _
                                     ws.Range(Source2(k, 1))).Address(0, 0)
            End If
        Next k
    Next i
    
    ' Write values from Target Array to Target Range. Since Target Array
    ' is too big, we are using 'm' instead of 'UBound(Target, 1)'.
    ws.Range(tgtFirstCell).Resize(m, UBound(Target, 2)).Value = Target
    
End Sub

Function getOneRowOneCol(SourceRange As Range, _
                         ByVal NumberOfCells As Long) _
         As Variant
    
    Dim r As Long
    r = SourceRange.Rows.Count
    Dim c As Long
    c = SourceRange.Columns.Count
    Dim NoRs As Long
    NoRs = r * (c - NumberOfCells + 1)
    Dim NoCs As Long
    NoCs = c * (r - NumberOfCells + 1)
    
    Dim Data As Variant
    ReDim Data(1 To NoRs + NoCs, 1 To 1)
    
    Dim rng As Range
    Dim i As Long
    Dim j As Long
    Dim k As Long
    
    ' Rows
    For i = 1 To r
        For j = 1 To c - NumberOfCells + 1
            Set rng = SourceRange.Cells(i, j).Resize(, NumberOfCells)
            k = k + 1
            Data(k, 1) = rng.Address(0, 0)
        Next j
    Next i
    
    ' Columns
    For j = 1 To c
        For i = 1 To r - NumberOfCells + 1
            Set rng = SourceRange.Cells(i, j).Resize(NumberOfCells)
            k = k + 1
            Data(k, 1) = rng.Address(0, 0)
        Next i
    Next j
    getOneRowOneCol = Data
    
'    Debug.Print UBound(Data)
'    For i = 1 To UBound(Data)
'        Debug.Print Data(i, 1)
'    Next i

End Function

【讨论】:

  • 非常感谢!像魅力一样工作!
猜你喜欢
  • 2019-06-04
  • 2017-11-18
  • 2015-06-04
  • 1970-01-01
  • 2010-12-05
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 2018-02-28
相关资源
最近更新 更多