2

以下のマトリックスを検討してください。

    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 のどちらを使用しても、各行の最後の要素の距離を見つけることができますか? 距離の定義距離は、指定された行列に最後の要素が配置された後のセルの数に他なりません。たとえば、言う -

  • 距離(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))

しかし、空白の間を処理できなかったため、機能していません。

タナクス、

4

2 に答える 2

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

説明しようとしています:

式は、trueの場合は評価され、そうでIIF(BoolExpression, TrueValue, FalseValue)ない場合は評価されます。したがって、のTrueスロットに別の列を配置すると、null以外の列が(列番号)の戻りをトリガーするまで、列が連続してテストされます。TrueValueBoolExpressionFalseValueIIFIsNull(Colx)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を窒息させるものからの視覚的な校正とテストは、マゾヒストの演習として残されています。

于 2013-01-01T13:07:12.470 に答える
2

別の方法... 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
于 2013-01-01T14:24:26.303 に答える