【问题标题】:Is it possible to find the last element distance for each excel row?是否可以找到每个 excel 行的最后一个元素距离?
【发布时间】:2012-12-16 03:23:02
【问题描述】:

考虑下面的矩阵:

    Col1    Col2    Col3    Col4    Col5    Col6    Col7
R1   x       x                        x
R2           x                x              x
R3                                                    x
R4           x        x       x
R5                                    x

现在使用 VBScript 或 ADO 哪一个可以找到每行最后一个元素的距离? 距离的定义 距离只不过是在给定矩阵中放置最后一个元素之后的单元格数。例如说 -

  • Dist(R1)=5

  • Dist(R4)=4 类似

我尝试了以下方法:

Option Explicit

Dim ArrayListTaskDetails : Set ArrayListTaskDetails = CreateObject("System.Collections.ArrayList")
Dim i,colcount

i=2
Do while i < = objExcel1.Application.WorksheetFunction.CountA(ob.Rows(1))

colcount=objExcel1.Application.WorksheetFunction.CountA(ob.Rows(i))
ArrayListTaskDetails.Add(colcount)

i=i+1
Loop

ArrayListTaskDetails.Sort()
i=ArrayListTaskDetails.Count
MsgBox("HighestColumnNumner:" & ArrayListTaskDetails(i-1))

但它不起作用,因为无法处理空白之间的问题。

感谢,

【问题讨论】:

  • @SiddharthRout 请看我的描述,但它不起作用!
  • 当然 :) 现在查看您的代码...
  • 我有vba和公式解决方案...让我完全测试一下。与此同时,您可能希望查看 Ekkehard.Horner 解决方案 :)
  • @SiddharthRout 公式解决方案对我不起作用,因为我正在做自动化,而 VBScript 代码将绰绰有余! :)
  • 我知道 ;) 但我将使用 vbscript 中的公式,这样我就不会做脏活...让 Excel 来做吧:P 给我一些时间...我想要在我发布之前对其进行完全测试...

标签: excel vbscript ado dao adodb


【解决方案1】:

另一种方式...在 VBSCRIPT 中使用公式

Dim oXLApp, oXLWb, oXLWs

Set oXLApp = CreateObject("Excel.Application")

'~~> Show Excel
oXLApp.Visible = True

'~~> Open files (Change as applicable)
Set oXLWb = oXLApp.Workbooks.Open("C:\MyFile.xlsx")
Set oXLWs = oXLWb.Sheets(1)

Dim lRow, i, tmp

With oXLWs
    lRow = .Range("A" & .Rows.Count).End(-4162).Row

    For i = 2 To lRow
        tmp = oXLApp.Evaluate("=ADDRESS(ROW(A" & i & "),MATCH(INDEX($" & i _
        & ":$" & i & ",MAX(IF($A" & i & ":$K" & i & "<>"""",COLUMN($A" & i _
        & ":$K" & i & ")))),A" & i & ":K" & i & "),1)")

        MsgBox .Range("A" & i).Value & " :- " & .Range(tmp).Column - 1
    Next
End With

截图

跟进

根据要求

Dim oXLApp, oXLWb, oXLWs

Set oXLApp = CreateObject("Excel.Application")

'~~> Hide Excel
oXLApp.Visible = True

'~~> Open files
Set oXLWb = oXLApp.Workbooks.Open("C:\MyFile.xlsx")
Set oXLWs = oXLWb.Sheets(1)

Dim lRow, i, tmp, MyArray, ColNo, ReturnName

With oXLWs
    lRow = .Range("A" & .Rows.Count).End(-4162).Row

    ColNo = .Columns.Count

    ReturnName = Split(.Cells(, ColNo).Address, "$", -1,1)(1)

    For i = 2 To lRow
        tmp = oXLApp.Evaluate("=ADDRESS(ROW(A" & i & "),MATCH(INDEX($" & i _
        & ":$" & i & ",MAX(IF($A" & i & ":$" & ReturnName & i & _
        "<>"""",COLUMN($A" & i & ":$" & ReturnName & i & ")))),A" & _
        i & ":" & ReturnName & i & "),1)")

        msgbox .Range("A" & i).Value & " :- " & .Range(tmp).Column - 1
    Next
End With

更多关注

Option Explicit

Dim oXLApp, oXLWb, oXLWs
Dim lRow, i, tmp, MyArray, ColNo, ReturnName

Set oXLApp = CreateObject("Excel.Application")

'~~> Hide Excel
oXLApp.Visible = True

'~~> Open files
Set oXLWb = oXLApp.Workbooks.Open("C:\MyFile.xlsx")

'~~> Set the Sheet 1 as sheet1
Set oXLWs = oXLWb.Sheets(1)

With oXLWs
    '~~> Get the last row in the worksheet
    lRow = .Cells.Find("*", .Range("A1"), -4123, 2, 1, 2).Row

    '~~> Get the total col count
    ColNo = .Columns.Count

    '~~> This will return the column name from column number
    ReturnName = Split(.Cells(, ColNo).Address, "$", -1, 1)(1)

    For i = 1 To lRow
        '~~> We are using the Evaluate to calculate the formula
        '~~> which will find our result
        tmp = oXLApp.Evaluate("=ADDRESS(ROW(A" & i & "),MATCH(INDEX($" & i _
        & ":$" & i & ",MAX(IF($A" & i & ":$" & ReturnName & i & _
        "<>"""",COLUMN($A" & i & ":$" & ReturnName & i & ")))),A" & _
        i & ":" & ReturnName & i & "),1)")

        '~~> This will return the column number
        MsgBox "Last Col in Row " & i & " is " & .Range(tmp).Column
    Next
End With

【讨论】:

  • 这里的一个问题是它如何用于n 列数?
  • 我已经把它带到了“K”。您可以将其扩展到您的任何需求
  • 你能评论一下我需要改变哪些部分以适合我的部分吗?
  • 只需将K 替换为":$K" &amp; i &amp; "&lt;&gt;"""",COLUMN($A" &amp; i _ &amp; ":$K" &amp; i &amp; ")))),A" &amp; i &amp; ":K" &amp; i 中的相关列号
  • 这应该回答你的问题:) siddharthrout.com/2012/10/02/…
【解决方案2】:

给定一个到 .xls 的 ADODB 连接,一个

"SELECT * FROM [Sheet2$]"

显示

PID     T1      T2      T3      T4      T5
11      1       <Null>  1       1       <Null>
14      1       1       1       <Null>  1
21      <Null>  <Null>  1       <Null>  <Null>
88      1       1       1       <Null>  <Null>
99      1       <Null>  <Null>  <Null>  <Null>
100     <Null>  <Null>  <Null>  <Null>  <Null>
101     1       1       1       1       1

一个嵌套的 IIF(IsNull(Col), [...], ColNum),如

"SELECT PID, IIF(IsNull(T5),IIF(IsNull(T4),IIF(IsNull(T3),IIF(IsNull(T2),IIF(IsNull(T1),0,1),2),3),4),5) As RMCol FROM [Sheet2$]"

会导致

PID     RMCol
11      4
14      5
21      3
88      3
99      1
100     0
101     5

试图解释:

如果BoolExpression 为真,则IIF(BoolExpression, TrueValue, FalseValue) 表达式的计算结果为TrueValue,否则为FalseValue;因此将另一个IIF 放入IsNull(Colx) 的True 槽中将连续测试列,直到非空列将触发FalseValue(列号)的返回。

是的:SQL 是一种处理任意数量行的工具(固定/精心设计的一组列);因此,如果您犯了将一组逻辑上不受限制的信息放入列而不是(另一个)表中的设计错误,那就是您付出的代价。

更新:

我犹豫要不要提出这个问题,因为从长远来看,所有的技巧和捷径都会失败 - 但是,无论如何你都必须从一开始就拥有一个体面的设计:

一个递归函数:

Function genIFF(n)
  If 1 = n Then
     genIFF = "IIF(IsNull(T1),0,1)"
  Else
     genIFF = "IIF(IsNull(T" & n & ")," & genIFF(n - 1) & "," & n & ")"
  End If
End Function

将愉快地创造:

  Dim n
  For n = 1 To 5
      WScript.Echo n, genIFF(n)
  Next

1 IIF(IsNull(T1),0,1)
2 IIF(IsNull(T2),IIF(IsNull(T1),0,1),2)
3 IIF(IsNull(T3),IIF(IsNull(T2),IIF(IsNull(T1),0,1),2),3)
4 IIF(IsNull(T4),IIF(IsNull(T3),IIF(IsNull(T2),IIF(IsNull(T1),0,1),2),3),4)
5 IIF(IsNull(T5),IIF(IsNull(T4),IIF(IsNull(T3),IIF(IsNull(T2),IIF(IsNull(T1),0,1),2),3),4),5)

甚至:

50 IIF(IsNull(T50),IIF(IsNull(T49),IIF(IsNull(T48),IIF(IsNull(T47),IIF(IsNull(T46),IIF(IsNull(T45),IIF(IsNull(
T44),IIF(IsNull(T43),IIF(IsNull(T42),IIF(IsNull(T41),IIF(IsNull(T40),IIF(IsNull(T39),IIF(IsNull(T38),IIF(IsNul
l(T37),IIF(IsNull(T36),IIF(IsNull(T35),IIF(IsNull(T34),IIF(IsNull(T33),IIF(IsNull(T32),IIF(IsNull(T31),IIF(IsN
ull(T30),IIF(IsNull(T29),IIF(IsNull(T28),IIF(IsNull(T27),IIF(IsNull(T26),IIF(IsNull(T25),IIF(IsNull(T24),IIF(I
sNull(T23),IIF(IsNull(T22),IIF(IsNull(T21),IIF(IsNull(T20),IIF(IsNull(T19),IIF(IsNull(T18),IIF(IsNull(T17),IIF
(IsNull(T16),IIF(IsNull(T15),IIF(IsNull(T14),IIF(IsNull(T13),IIF(IsNull(T12),IIF(IsNull(T11),IIF(IsNull(T10),I
IF(IsNull(T9),IIF(IsNull(T8),IIF(IsNull(T7),IIF(IsNull(T6),IIF(IsNull(T5),IIF(IsNull(T4),IIF(IsNull(T3),IIF(Is
Null(T2),IIF(IsNull(T1),0,1),2),3),4),5),6),7),8),9),10),11),12),13),14),15),16),17),18),19),20),21),22),23),2
4),25),26),27),28),29),30),31),32),33),34),35),36),37),38),39),40),41),42),43),44),45),46),47),48),49),50)

对于 n Excel 将在嵌套 IIF 上窒息的内容进行视觉校对和测试留作自虐狂的练习。

【讨论】:

  • 看不懂逻辑,能不能也解释一下?
  • 如果我有 50 列,那么我是否需要以这种嵌套方式编写所有内容?
  • 对不起,你是 100% 正确的!那么有没有机会让嵌套条件变得简单或泛化?
  • 不错。但现在我在想如何将它与您发布的上述内容连接到 ADODB!在这方面有什么帮助吗?看来你的完整代码与ADO 对我理解完整的逻辑更有帮助。再次fantastic logic 你提供了但有点分散!
  • 我对看你的代码太感兴趣了,所以我可以有完整的格式,以便更清楚地理解它的所有中断。
猜你喜欢
  • 2015-07-28
  • 2016-12-22
  • 1970-01-01
  • 2014-06-19
  • 2021-09-23
  • 2012-01-21
  • 2020-12-05
  • 2016-10-09
  • 1970-01-01
相关资源
最近更新 更多