2017-08-11 157 views
2

我正在計算出用戶選擇顯示在工作表按鈕I.e旁邊工作表頂部的行數。按鈕顯示「生成電子郵件」,旁邊顯示「已選擇x項」。VBA Rows.Count in Selection

由於這是每次更新的選擇改變時,我有以下代碼:

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
    Sheet1.Range("E1") = Target.Rows.Count & " items selected" 
End Sub 

此工作正常,如果用戶選擇連續行,對於例如7:10返回4.

我的問題是如果用戶選擇了行7和10.它只會返回1(選擇的第一部分中的行)。

從我發現,沒有辦法從屬性中獲取這個值,但我無法得到我的頭周圍如何遍歷選擇/目標的所有部分,並計算行的總和。那麼也有可能用戶選擇說A7,C7和A10。 A7和C7涉及相同的項目,所以這應該只能真正被視爲一個,而不是兩個,我認爲我的假設代碼會做...

有沒有人試圖實現這一點,並已成功或可能點我在一些可能有所幫助的房產方向?我嘗試了一個單獨的功能來實現它,但那也不起作用。

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
    Sheet1.Range("E1") = getRowCount(Target) & " items selected" 
End Sub 

Function getRowCount(selectedRanges As Ranges) 
    rowCount = 0 
    For Each subRange In selectedRanges 
    rowCount = rowCount + subRange.Rows.Count 
    Next 

    getRowCount = rowCount 
End Function 
+0

Esperadoce - 感謝編輯格式,我只是下載了應用程序,希望添加格式,但你擊敗了我! –

回答

2

我認爲這會工作。 (沒有當我嘗試了。)

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
    'Create a range containing just column A 
    Dim subRange As Range 
    Dim r As Range 
    For Each subRange In Target.Areas 
     If r Is Nothing Then 
      Set r = subRange.EntireRow.Columns(1) 
     Else 
      Set r = Union(r, subRange.EntireRow.Columns(1)) 
     End If 
    Next 
    'Count how many cells in the combined column A range 
    Sheet1.Range("E1") = r.Cells.Count & " items selected" 
End Sub 
+0

我打算將其標記爲答案,因爲它是我已經整合的第一個,並且它的工作很快。這不是我曾經想過的方式,但是作爲一種簡單的方法來進行計算對我來說是有意義的。接下來的這一部分不是我原來的問題的一部分,但是向前移動,是否有一種方法可以遍歷r(?)以獲取每行中各列的數據? –

+0

@OliBarton在我的代碼中,'r'與原始選擇完全無關,只是它指向每一行的列A.所以如果你的選擇是'B5:B10,D8:D12,C15:J20',那麼'r'就是'A5:A12,A15:A20'。所以如果你在'D5:D12,D15:D20'之後,你可以遍歷'r'中的每個單元並使用'Offset(0,3)'到達相應的D列(或者只是遍歷'r。 EntireRow.Coumns(「D」)'),但如果你只對'D8:D12,D15:D20'感興趣,則需要遍歷'Intersect(r.EntireRow.Columns(「D」),Target)'' 。 – YowE3K

0

您需要計算用戶選擇的每個Area中的行。
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/range-areas-property-excel

Private Sub Worksheet_SelectionChange(ByVal Target As Range) 

    Dim rArea As Range 
    Dim lCount As Long 

    For Each rArea In Selection.Areas 
     lCount = lCount + rArea.Rows.Count 
    Next rArea 

    Sheet1.Range("E1") = lCount 

End Sub 
+0

你打我20秒! :D(PS)關於如何避免在多個領域出現重複計數行的任何建議?在OP的情況下可能不是問題,但如果您有任何明智的想法,仍然可以很好地知道以供將來參考) – YowE3K

+0

在我讀你的第一條評論之前,我沒有考慮過重複計算。現在想想它。 –

+0

而且,在重新閱讀這個問題時,聽起來好像在**的情況下會發生**( – YowE3K

0
Private Sub Worksheet_SelectionChange(ByVal Target As Range) 
Dim cell As Range 
Dim i, currentRow As Long: i = 0 
'get row of first cell in range 
currentRow = Target.Cells(1, 1).row 

For Each cell In Target 
    'if row is different, then increase number of items, as it's next item 
    If Not currentRow = cell.row Then 
     i = i + 1 
     currentRow = cell.row 
    End If 
Next cell 

Range("E1").Value = i 

End Sub 
+0

您可以選擇不按順序,然後下一個單元格不一定低於前一個單元格 – Wolfie

1
Sub NumberOfRowsSelected() 
Dim vMatch As Variant, aRows() As Long, r As Range, x As Long 

ReDim Preserve aRows(x) 
aRows(x) = 0 

For Each r In Selection.Cells 
    vMatch = Application.Match(r.Row, aRows, 0) 

    If IsError(vMatch) Then 
     x = x + 1 
     ReDim Preserve aRows(0 To x) 
     aRows(x) = r.Row 
    End If 
Next r 

MsgBox UBound(aRows) 

End Sub 

修改過的代碼轉換爲功能

Sub NumberOfRowsSelected() 
    MsgBox RowsCount(Selection) 
End Sub 

Function RowsCount(rRange As Range) As Long 
Dim vMatch As Variant, aRows() As Long, r As Range, x As Long 

ReDim Preserve aRows(x) 
aRows(x) = 0 

For Each r In rRange.Cells 
    vMatch = Application.Match(r.Row, aRows, 0) 

    If IsError(vMatch) Then 
     x = x + 1 
     ReDim Preserve aRows(0 To x) 
     aRows(x) = r.Row 
    End If 
Next r 

RowsCount = UBound(aRows) 

End Function 
+0

您對'aRows'的設置使我困惑,您'ReDim'它使用未定義的'x'大小爲0(爲什麼不僅僅是將它調整到合適的大小),然後爲第0個元素賦值0,它默認情況下已經是默認值了......如果這是一個函數,那麼它會更有用,返回值比調用魔鬼('MsgBox') – Wolfie

+0

默認情況下數組以零計數器開始。我開始使用零計數器數組,因爲x也是零,我沒有給x賦值,所以x默認爲零。 aRows(x)在這意味着aRows(0)。在Excel中,行從1開始,在Excel中沒有0行。所以aRows(x)= 0意味着我在說aRows(0_Counter)= 0作爲行值來將aRows變量設置爲數組。所以Match函數會將它視爲數組,因爲我已經在aRows數組中加載了一個0 Row值,所以不會拋出任何錯誤。 – Sixthsense

+0

啊好吧,考慮在未來的答案中加入一些評論來說明這樣的點,這些點對於讀者來說並不是立即顯而易見的:)感謝 – Wolfie

1

一種不同的方法,建立檢查行的字符串似乎相當直截了當,以避免雙重計算。查看評論的詳細信息:

Function getRowCount(rng As Range) As Long 
    Dim c As Range 
    ' Keep track of which rows we've already counted 
    Dim countedrows As String: countedrows = "," 
    ' Loop over cells in range 
    For Each c In rng 
     ' Check if already counted 
     If Not InStr(countedrows, "," & c.Row & ",") > 0 Then 
      ' Add to counted list 
      countedrows = countedrows & c.Row & "," 
     End If 
    Next c 
    ' Get number of rows counted 
    Dim rowsarr() As String: rowsarr = Split(countedrows, ",") 
    getRowCount = UBound(rowsarr) - LBound(rowsarr) - 1 
End Function 
+0

這會是一個問題,如果我們有例如'13,'然後'3,'算數?我的意見完全一樣:) –

+0

你說得對,我只考慮了'1,'和'13'的情況!我編輯了我的答案,以確保每個數字的雙方都有一個逗號,現在應該可以工作。 – Wolfie

+0

感謝您的回覆,我很有信心這會在閱讀時發揮作用,但我已經將它放到了我的工作簿中,並且令人生厭的是它正在計算重複的行= /只需檢查,我是否應該簡單地將它調用如下:Dim lCount As Long - 然後 - lCount = getRowCount(選擇)? –