2011-05-04 44 views
9

一個VBA陣列誰能給我VBA代碼,將從Excel片採取的範圍(行或列)和填充列表/陣列與所述唯一值, 即:填充唯一值到從Excel

table 
table 
chair 
table 
stool 
stool 
stool 
chair 

當宏運行將創建一個數組一些事情,如:

fur[0]=table 
fur[1]=chair 
fur[2]=stool 
+0

,我們談論的VB或VBA? (VB - >外部程序讀取Excel文件或使用互操作來控制Excel; VBA - > VB的應用程序...見excel宏編輯器) – DarkSquirrel42 2011-05-04 22:07:12

+0

以及我在我的文章中說過宏,但是對不起VBA – DevilWAH 2011-05-04 22:29:26

+0

您應該發佈你的編輯作爲一個新問題,否則它不會得到解決。 – 2011-05-05 19:19:06

回答

11

在這種情況下我總是用這樣的代碼(只需確保定界符您選擇不在搜索範圍的一部分)

Dim tmp As String 
Dim arr() As String 

If Not Selection Is Nothing Then 
    For Each cell In Selection 
     If (cell <> "") And (InStr(tmp, cell) = 0) Then 
     tmp = tmp & cell & "|" 
     End If 
    Next cell 
End If 

If Len(tmp) > 0 Then tmp = Left(tmp, Len(tmp) - 1) 

arr = Split(tmp, "|") 
+0

我喜歡這個代碼ty – DevilWAH 2011-05-04 23:06:10

+3

但是什麼它是否與「腳凳」,然後是「凳子」?也許你應該先嚐試一下...... – 2011-05-05 00:11:33

+0

它很高興地接受一個包含以下字符串的列表ASR端口供應,ASR端口供應一般問題,ASR端口供應無操作,並彈出陣列,因爲它們是唯一的 – DevilWAH 2011-05-05 08:48:19

21
Sub GetUniqueAndCount() 

    Dim d As Object, c As Range, k, tmp As String 

    Set d = CreateObject("scripting.dictionary") 
    For Each c In Selection 
     tmp = Trim(c.Value) 
     If Len(tmp) > 0 Then d(tmp) = d(tmp) + 1 
    Next c 

    For Each k In d.keys 
     Debug.Print k, d(k) 
    Next k 

End Sub 
+1

也是一個很好的代碼:)兩者似乎都是我所需要的。乾杯 – DevilWAH 2011-05-05 08:52:50

+1

+1很好編碼 – brettdj 2014-02-02 10:43:50

4

這是老派的做法。

它會比循環遍歷單元更快地執行(例如,For Each cell In Selection),並且只要您有矩形選擇(即不是按住Ctrl鍵選擇一堆隨機單元格),它就會可靠。

Sub FindUnique() 

    Dim varIn As Variant 
    Dim varUnique As Variant 
    Dim iInCol As Long 
    Dim iInRow As Long 
    Dim iUnique As Long 
    Dim nUnique As Long 
    Dim isUnique As Boolean 

    varIn = Selection 
    ReDim varUnique(1 To UBound(varIn, 1) * UBound(varIn, 2)) 

    nUnique = 0 
    For iInRow = LBound(varIn, 1) To UBound(varIn, 1) 
     For iInCol = LBound(varIn, 2) To UBound(varIn, 2) 

      isUnique = True 
      For iUnique = 1 To nUnique 
       If varIn(iInRow, iInCol) = varUnique(iUnique) Then 
        isUnique = False 
        Exit For 
       End If 
      Next iUnique 

      If isUnique = True Then 
       nUnique = nUnique + 1 
       varUnique(nUnique) = varIn(iInRow, iInCol) 
      End If 

     Next iInCol 
    Next iInRow 
    '// varUnique now contains only the unique values. 
    '// Trim off the empty elements: 
    ReDim Preserve varUnique(1 To nUnique) 
End Sub 
+0

必須同意這是一個很好的方法來做到這一點。一旦代碼的其餘部分工作,我想我想我會更新它實現這一點。 – DevilWAH 2011-05-05 12:09:19

7

將Tim的Dictionary方法與來自Jean_Francois的變體數組結合在一起。

要在陣列中objDict.keys

enter image description here

Sub A_Unique_B() 
Dim X 
Dim objDict As Object 
Dim lngRow As Long 

Set objDict = CreateObject("Scripting.Dictionary") 
X = Application.Transpose(Range([a1], Cells(Rows.Count, "A").End(xlUp))) 

For lngRow = 1 To UBound(X, 1) 
    objDict(X(lngRow)) = 1 
Next 
Range("B1:B" & objDict.Count) = Application.Transpose(objDict.keys) 
End Sub 
0

老學校的方法是我最喜歡的選擇。謝謝。這確實很快。但我沒有使用redim。這裏雖然是我真實世界的例子,我爲一列中找到的每個唯一「關鍵字」積累值並將其移入數組(例如,對於員工而言,值是每天工作的小時數)。然後,我將每個鍵的最終值放入活動工作表的總計區域。對於那些想要對這裏發生的事情進行痛苦細節的人,我已經廣泛地發表了評論。有限的錯誤檢查由此代碼完成。

Sub GetActualTotals() 
' 
' GetActualTotals Macro 
' 
' This macro accumulates values for each unique employee from the active 
' spreadsheet. 
' 
' History 
' October 2016 - Version 1 
' 
' Invocation 
' I created a button labeled "Get Totals" on the Active Sheet that invokes 
' this macro. 
' 
Dim ResourceName As String 
Dim TotalHours As Double 
Dim TotalPercent As Double 
Dim IsUnique As Boolean 
Dim FirstRow, LastRow, LastColumn, LastResource, nUnique As Long 
Dim CurResource, CurrentRow, i, j As Integer 
Dim Resource(1000, 2) As Variant 
Dim Rng, r As Range 
' 
' INITIALIZATIONS 
' 
' These are index numbers for the Resource array 
' 
Const RName = 0 
Const TotHours = 1 
Const TotPercent = 2 
' 
' Set the maximum number of resources we'll 
' process. 
' 
Const ResourceLimit = 1000 
' 
' We are counting on there being no unintended data 
' in the spreadsheet. 
' 
' It won't matter if the cells are empty though. It just 
' may take longer to run the macro. 
' But if there is data where this macro does not expect it, 
' assume unpredictable results. 
' 
' There are some hardcoded values used. 
' This macro just happens to expect the names to be in Column C (or 3). 
' 
' Get the last row in the spreadsheet: 
' 
LastRow = Cells.Find(What:="*", _ 
       After:=Range("C1"), _ 
       LookAt:=xlPart, _ 
       LookIn:=xlFormulas, _ 
       SearchOrder:=xlByRows, _ 
       SearchDirection:=xlPrevious, _ 
       MatchCase:=False).Row 
' 
' Furthermore, this macro banks on the first actual name to be in C6. 
' so if the last row is row 65, the range we'll work with 
' will evaluate to "C6:C65" 
' 
FirstRow = 6 
Rng = "C" & FirstRow & ":C" & LastRow 
Set r = Range(Rng) 
' 
' Initialize the resource array to be empty (even though we don't really 
' need to but I'm old school). 
' 
For CurResource = 0 To ResourceLimit 
    Resource(CurResource, RName) = "" 
    Resource(CurResource, TotHours) = 0 
    Resource(CurResource, TotPercent) = 0 
Next CurResource 
' 
' Start the resource counter at 0. The counter will represent the number of 
' unique entries. 
' 
nUnique = 0 
' 
' LET'S GO 
' 
' Loop from the first relative row and the last relative row 
' to process all the cells in the spreadsheet we are interested in 
' 
For i = 1 To LastRow - FirstRow 
' 
' Loop here for all unique entries. For any 
' new unique entry, that array element will be 
' initialized in the second if statement. 
' 
    IsUnique = True 
    For j = 1 To nUnique 
' 
' If the current row element has a resource name and is already 
' in the resource array, then accumulate the totals for that 
' Resource Name. We then have to set IsUnique to false and 
' exit the for loop to make sure we don't populate 
' a new array element in the next if statement. 
' 
     If r.Cells(i, 1).Value = Resource(j, RName) Then 
      IsUnique = False 
      Resource(j, TotHours) = Resource(j, TotHours) + _ 
      r.Cells(i, 4).Value 
      Resource(j, TotPercent) = Resource(j, TotPercent) + _ 
      r.Cells(i,5).Value 
      Exit For 
     End If 
    Next j 
' 
' If the resource name is unique then copy the initial 
' values we find into the next resource array element. 
' I ignore any null cells. (If the cell has a blank you might 
' want to add a Trim to the cell). Not much error checking for 
' the numerical values either. 
' 
    If ((IsUnique) And (r.Cells(i, 1).Value <> "")) Then 
     nUnique = nUnique + 1 
     Resource(nUnique, RName) = r.Cells(i, 1).Value 
     Resource(nUnique, TotHours) = Resource(nUnique, TotHours) + _ 
     r.Cells(i, 4).Value 
     Resource(nUnique, TotPercent) = Resource(nUnique, TotPercent) + _ 
     r.Cells(i, 5).Value 
    End If     
Next i 
' 
' Done processing all rows 
' 
' (For readability) Set the last resource counter to the last value of 
' nUnique. 
' Set the current row to the first relative row in the range (r=the range). 
' 
LastResource = nUnique 
CurrentRow = 1 
' 
' Populate the destination cells with the accumulated values for 
' each unique resource name. 
' 
For CurResource = 1 To LastResource 
    r.Cells(CurrentRow, 7).Value = Resource(CurResource, RName) 
    r.Cells(CurrentRow, 8).Value = Resource(CurResource, TotHours) 
    r.Cells(CurrentRow, 9).Value = Resource(CurResource, TotPercent) 
    CurrentRow = CurrentRow + 1 
Next CurResource 

End Sub 
0

另一種方式......

Sub get_unique() 
Dim unique_string As String 
    lr = Sheets("data").Cells(Sheets("data").Rows.Count, 1).End(xlUp).Row 
    Set range1 = Sheets("data").Range("A2:A" & lr) 
    For Each cel In range1 
     If Not InStr(output, cel.Value) > 0 Then 
      unique_string = unique_string & cel.Value & "," 
     End If 
    Next 
End Sub