Ok, I have the code below, which takes 18 different words, all in Column A rows 1 to 18, and tries them in all different combos to find a seven word palindrome. I am pretty sure the code will get it done, but it just searches for a LONG time. I know there's a way to check the first and last letters of the combos, to make sure they're the same, before the code runs them through the REVERSE function, I just can't figure out how to do it. I am very new to this.In other words, each time it puts together 7 of the words, if it didn't have to go through the REVERSE function, a ton of time would be saved, and verification that the first and last letters match would do that. Thanks in advance for any help
Sub SevenDrome()
Dim count As Integer
count = 0
Dim wordtest As String
Dim wordpal As String
For j = 1 To 18
For k = 1 To 18
For l = 1 To 18
For m = 1 To 18
For n = 1 To 18
For o = 1 To 18
For p = 1 To 18
wordtest = Cells(j, 1) & Cells(k, 1) & Cells(l, 1) & Cells(m, 1) & Cells(n, 1) & Cells(o, 1) & Cells(p, 1)
wordpal = REVERSE(wordtest)
If wordtest = wordpal Then
count = count + 1
Cells(count, 7) = wordtest
End If
Next p
Next o
Next n
Next m
Next l
Next k
Next j
End Sub
Try, This results in 104,976 which takes less than 2 seconds.
Sub test()
Dim a(1 To 18)
Dim vR(1 To 1000000, 1 To 1)
Dim cnt As Long
Dim i As Integer, k As Integer, l As Integer
Dim m As Integer, n As Integer, o As Integer
For i = 1 To 18
a(i) = Range("a" & i)
Next i
For j = 1 To 18
For k = 1 To 18
If a(j) = a(k) Then
For l = 1 To 18
For m = 1 To 18
If a(l) = a(m) Then
For n = 1 To 18
For o = 1 To 18
If a(n) = a(o) Then
For p = 1 To 18
cnt = cnt + 1
vR(cnt, 1) = a(j) & a(l) & a(n) & a(p) & a(o) & a(m) & a(k)
DoEvents
Next p
End If
Next o
Next n
End If
Next m
Next l
End If
Next k
Next j
Range("g1").Resize(cnt) = vR
End Sub
Data image
Result Image
If each cell has more than 2 characters, you can do as follows.
Sub test2()
Dim a(1 To 18)
Dim vR(1 To 1000000, 1 To 1)
Dim cnt As Long
Dim i As Integer, k As Integer, l As Integer
Dim m As Integer, n As Integer, o As Integer
For i = 1 To 18
a(i) = Range("a" & i)
Next i
For j = 1 To 18
For k = 1 To 18
If a(j) = Reverse(a(k)) Then
For l = 1 To 18
For m = 1 To 18
If a(l) = Reverse(a(m)) Then
For n = 1 To 18
For o = 1 To 18
If a(n) = Reverse(a(o)) Then
For p = 1 To 18
If a(p) = Reverse(a(p)) Then
cnt = cnt + 1
vR(cnt, 1) = a(j) & a(l) & a(n) & a(p) & a(o) & a(m) & a(k)
DoEvents
End If
Next p
End If
Next o
Next n
End If
Next m
Next l
End If
Next k
Next j
Range("g1").CurrentRegion.Clear
If cnt Then
Range("g1").Resize(cnt) = vR
End If
End Sub
Function Reverse(s)
Dim i As Integer
Dim myS As String
For i = Len(s) To 1 Step -1
myS = myS & Mid(s, i, 1)
Next i
Reverse = myS
End Function
Case 2 Data
Case 2 Result
Related
The task I am doing requires to read and print a matrix from txt file, then create a new matrix B whose elements are the average of the row and column from A matrix, and then find the lowest valued number in the B matrix, print it and print its indexes (If the element "1" is the lowest and it is in the 2nd row and 3rd column, there should be printed below the matrix B "The lowest element is 1 with indexes 2;3".
For example the element B23 should be the average of the sum of the elements of row 2 and column 3 of matrix A. There is a short matrix example in the code below.
The input for the A matrix is coming from txt file, where on the first row are m and n (rows and columns) and below them is the actual matirx.
Example:
Thank you in advance!
Here is the code:
`
" Example for input
3 3
2 9 8
4 2 5
5 2 3
Expected answear:
Matrix A
2.00 9.00 8.00
4.00 2.00 5.00
5.00 2.00 3.00
Matrix B
15.00 16.00 17.50
11.00 12.00 13.50
10.50 11.50 13.00
The lowest element is 10.50 with indexes 3,1.
Option Explicit
Sub Matrix()
Dim m As Integer, n As Integer, A() As Single, _
MaxA As Single, r_Max As Integer
Call InputMatrix(m, n, A)
Call NewMatrixB(A, m)
End Sub
Sub InputMatrix(m As Integer, n As Integer, A() As Single)
Dim i As Integer, j As Integer
Dim FName As String
FName = InputBox("Vuvedete ime na fail s vhodni danni", _
"matrix", "H:\School\matrix.txt")
If Dir(FName) = "" Then
MsgBox ("Failut " & FName & " ne e nameren!")
Stop
End If
Close #1
Open FName For Input As #1
Input #1, m, n
ReDim A(m, n)
For i = 1 To m
For j = 1 To n
Input #1, A(i, j)
Next j
Next i
Close #1
Worksheets("Sheet1").Activate
Cells.Clear
Call OutMatrix(m, n, A, 1, "Matrix A")
End Sub
Sub OutMatrix(m As Integer, n As Integer, A() As Single, _
r As Integer, title As String)
Dim i As Integer, j As Integer
With Cells(r, 1)
.Value = title
.Font.Size = 14
.Font.Bold = True
End With
For i = 1 To m
For j = 1 To n
Cells(r + i, j).Value = A(i, j)
Cells(r + i, j).NumberFormat = "0.00"
Next j
Next i
End Sub
Sub NewMatrixB(Data As Variant, m As Integer)
Dim X As Variant
X = Data
Dim numRows As Long
Dim numCols As Long
numRows = UBound(X, 1)
numCols = UBound(X, 2)
ReDim rowSum(1 To numCols) As Double
ReDim colSum(1 To numRows) As Double
Dim r As Long
Dim c As Long
For r = 1 To numRows
For c = 1 To numCols
rowSum(c) = rowSum(c) + X(r, c)
colSum(r) = colSum(r) + X(r, c)
Next
Next
ReDim B(1 To numRows, 1 To numCols) As Double
For r = 1 To numRows
For c = 1 To numCols
B(r, c) = (rowSum(c) + colSum(r)) / 2
Next
Next
With Cells(m + 3, 1)
.Value = "Matrix B"
.Font.Size = 14
.Font.Bold = True
End With
Cells(m + 4, 1).Resize(numRows, numCols) = B
Worksheets("Sheet1").Range("A1:X100").NumberFormat = "0.00"
Dim Min As Integer
End Sub
Sub Minimum(m As Integer, Matrixxx As Single)
MsgBox Application.Min(Matrixxx)
End Sub
As far as I went, my code is up to the new matrix B and printing it, but I have trouble finding the new one and making it a type, where I can get the indexes as well. I also do have trouble with the syntacsis, Have been coding 5years ago in java.
If you need to return a value then define a function. To return more than one value use an array.
Option Explicit
Sub Process_Matrix()
' define matrices
Dim A As Variant, B As Variant
A = InputMatrix("matrix.txt") '"H:\School\matrix.txt")
Call OutMatrix("Matrix A", Sheet1.Cells(1, 1), A)
B = NewMatrixB(A)
Call OutMatrix("Matrix B", Sheet1.Cells(12, 1), B)
Dim idx, msg As String
idx = getMin(B)
msg = "Min = " & B(idx(0), idx(1)) & " at B(" & idx(0) & "," & idx(1) & ")"
MsgBox msg, vbInformation
End Sub
Function getMin(ByRef X) As Variant
Dim i As Long, j As Long, m As Double, ar(0 To 1) As Long
m = X(1, 1)
ar(0) = 1
ar(1) = 1
For i = 1 To UBound(X)
For j = 1 To UBound(X, 2)
If X(i, j) < m Then
m = X(i, j)
ar(0) = i
ar(1) = j
End If
Next
Next
getMin = ar
End Function
Function InputMatrix(Fname As String) As Variant
Dim i As Long, j As Long, m As Long, n As Long, A() As Single
Fname = InputBox("Vuvedete ime na fail s vhodni danni", _
"matrix", Fname)
If Dir(Fname) = "" Then
MsgBox "Failut " & Fname & " ne e nameren!", vbCritical
Stop
End If
Close #1
Open Fname For Input As #1
Input #1, m, n
ReDim A(1 To m, 1 To n)
For i = 1 To m
For j = 1 To n
Input #1, A(i, j)
Next j
Next i
Close #1
InputMatrix = A
End Function
Sub OutMatrix(title As String, rng As Range, ByRef X)
With rng
.Value = title
.Font.Size = 14
.Font.Bold = True
With .Offset(1, 0).Resize(UBound(X), UBound(X, 2))
.Value = X
.NumberFormat = "0.00"
End With
End With
End Sub
Function NewMatrixB(ByRef X) As Variant
Dim B, rowSum, colSum
Dim numRows As Long, numCols As Long, r As Long, c As Long
numRows = UBound(X, 1)
numCols = UBound(X, 2)
ReDim rowSum(1 To numRows) As Double
ReDim colSum(1 To numCols) As Double
For r = 1 To numRows
For c = 1 To numCols
rowSum(c) = rowSum(c) + X(r, c)
colSum(r) = colSum(r) + X(r, c)
Next
Next
ReDim B(1 To numRows, 1 To numCols) As Double
For r = 1 To numRows
For c = 1 To numCols
B(r, c) = (rowSum(c) + colSum(r)) / 2
Next
Next
NewMatrixB = B
End Function
I have a table with two Columns Product and Price($).
Product
Price($)
A
100
B
400
C
350
D
50
E
515
F
140
I am trying to use vba to get combination of value of all products that will not exceed $500. I have been trying with this code and I am not sure how to proceed from this point on.
Sub getCombination()
Dim price As Long
Dim limit As Long
Dim i As Integer
Dim j As Integer
Dim combination As String
limit = 500
combination = ""
Range("B2").Activate
price = Range("B2").Value
For i = 1 To 6
For j = 1 To 6
If price <= limit Then
price = price + ActiveCell.Offset(j, 0).Value
combination = combination & ActiveCell.Offset(0, -1).Value & "," & ActiveCell.Offset(1, -1).Value
End If
Next j
Next i
ActiveCell.Offset(1, 0).Activate
MsgBox combination
End Sub
My Expected output is something like
A,B
A,C
A,C,D
B,D
C,F
A,D
C,D
(Please note: Not All output combinations are specified here!)
How should I proceed with the existing code? Or do I really have a better way for me to implement this?
Since the item can be used or not, that is a binary response. Using a binary number with the same number of digits as the number of items we can do all the combinations and do the testing:
Sub getCombination()
Dim rngArr As Variant
rngArr = ActiveSheet.Range("A2:B7")
Dim cnt As Long
cnt = 2 ^ UBound(rngArr, 1) - 1
Dim OutArray As Variant
ReDim OutArray(1 To cnt, 1 To 2)
Dim k As Long
k = 1
Dim i As Long
For i = 1 To cnt
Dim bin As String
bin = Application.Dec2Bin(i, UBound(rngArr, 1))
Dim delim As String
delim = ""
Dim j As Long
For j = 1 To UBound(rngArr, 1)
If Mid(bin, j, 1) = "1" Then
OutArray(k, 1) = OutArray(k, 1) & delim & rngArr(j, 1)
delim = ", "
OutArray(k, 2) = OutArray(k, 2) + rngArr(j, 2)
End If
Next j
If OutArray(k, 2) <= 500 Then
k = k + 1
Else
OutArray(k, 1) = ""
OutArray(k, 2) = 0
End If
Next i
Dim fnlarr As Variant
ReDim fnlarr(1 To k - 1)
For i = 1 To k - 1
fnlarr(i) = OutArray(i, 1)
Next i
Debug.Print Join(fnlarr, " | ")
End Sub
I am a newbie vba coder here.
I have created an .xlsm with userform. Everything works fine in my computer, but when I send the file over via email, the recipient will encounter the following issues when opening the file:
I added an event handler on Workbook_Open to automatically open the userform. When the recipient open the file, it will receive this error and Debug button returns to this line:
When Submit button of the Userform is clicked, the data is supposed to be transferred to 'ThisWorkbook' but instead it creates a new file (i guess the previous version) and paste the data there.
Can anyone help me to figure out what went wrong with my file? Thank you.
Below is my code:
Inside Workbook Event Handler:
Sub Workbook_Open()
RunForm
End Sub
Module1:
Option Explicit
Option Base 1
Sub PopulateComboBox()
Dim PaymentTerms() As String, PaymentFreq() As String, PaymentTermsAlt() As String
Dim i As Integer, j As Integer, m As Integer, n As Integer, o As Integer
j = WorksheetFunction.CountA(Sheets("Populate").Columns("A:A"))
n = WorksheetFunction.CountA(Sheets("Populate").Columns("B:B"))
ReDim PaymentTerms(j - 1) As String
ReDim PaymentFreq(n - 1) As String
ReDim PaymentTermsAlt(j - 1) As String
For i = 1 To j - 1
PaymentTerms(i) = ThisWorkbook.Sheets("Populate").Range("A2:A" & (j - 1)).Cells(i, 1)
UserForm1.ComboTerms.AddItem PaymentTerms(i)
Next i
For m = 1 To n - 1
PaymentFreq(m) = ThisWorkbook.Sheets("Populate").Range("B2:B" & (n - 1)).Cells(m, 1)
UserForm1.ComboFreq.AddItem PaymentFreq(m)
Next m
For o = 1 To j - 1
PaymentTermsAlt(o) = ThisWorkbook.Sheets("Populate").Range("A2:A" & (j - 1)).Cells(o, 1)
UserForm1.ComboTermsAlt.AddItem PaymentTermsAlt(o)
Next o
UserForm1.ComboTerms.Text = PaymentTerms(1)
UserForm1.ComboFreq.Text = PaymentFreq(1)
UserForm1.ComboTermsAlt.Text = PaymentTermsAlt(1)
End Sub
Sub RunForm()
ThisWorkbook.Sheets("Printout").Activate
UserForm1.Show
End Sub
Inside Userform:
Option Explicit
Sub CommandButton1_Click()
Application.ScreenUpdating = False
If Not IsNumeric(BasePay) Or Not IsNumeric(Interest) Then
MsgBox ("Please Enter Numeric Value for Base Pay or Interest Rate")
Exit Sub
End If
If BasePay < 0 Or Interest < 0 Then
MsgBox ("Base Pay or Interest cannot be negative value")
Exit Sub
End If
ThisWorkbook.Sheets("Printout").Range("A1") = "Prepared For " & ClientName
ThisWorkbook.Sheets("Printout").Range("O1").Value = BasePay.Text
ThisWorkbook.Sheets("Printout").Range("S2").Value = Interest.Text / 100
ThisWorkbook.Sheets("Printout").Range("L3").Value = ComboTerms.Text
ThisWorkbook.Sheets("Printout").Range("O3").Value = ComboFreq.Text
ThisWorkbook.Sheets("Printout").Range("Q2").Value = ComboTermsAlt.Text
If NewCar Then
ThisWorkbook.Sheets("Printout").Range("U2").Value = "New"
Else
ThisWorkbook.Sheets("Printout").Range("U2").Value = "Used"
End If
'----- Transfer Add-On Items to Printout Sheet ---------
Dim i As Integer
Dim j As Integer
Dim k As Integer
k = 6
For i = 1 To 9
ThisWorkbook.Sheets("Printout").Cells(k, 1).MergeArea.ClearContents
k = k + 2
Next
k = 6
For i = 10 To 18
ThisWorkbook.Sheets("Printout").Cells(k, 5).MergeArea.ClearContents
k = k + 2
Next
k = 6
For i = 19 To 27
ThisWorkbook.Sheets("Printout").Cells(k, 9).MergeArea.ClearContents
k = k + 2
Next
k = 6
For i = 28 To 36
ThisWorkbook.Sheets("Printout").Cells(k, 13).MergeArea.ClearContents
k = k + 2
Next
'---- Category 1 ------
i = 6
For j = 1 To 9
If UserForm1.Controls("Checkbox" & j).Value = True Then
ThisWorkbook.Sheets("Printout").Range("A" & i).Value = Me.Controls("Checkbox" & j).Caption
i = i + 2
Else
ThisWorkbook.Sheets("Printout").Range("A" & i).Value = ""
End If
Next j
'---- Category 2 ------
i = 6
For j = 10 To 18
If UserForm1.Controls("Checkbox" & j).Value = True Then
ThisWorkbook.Sheets("Printout").Range("E" & i).Value = Me.Controls("Checkbox" & j).Caption
i = i + 2
Else
ThisWorkbook.Sheets("Printout").Range("E" & i).Value = ""
End If
Next j
'---- Category 3 ------
i = 6
For j = 19 To 27
If UserForm1.Controls("Checkbox" & j).Value = True Then
ThisWorkbook.Sheets("Printout").Range("I" & i).Value = Me.Controls("Checkbox" & j).Caption
i = i + 2
Else
ThisWorkbook.Sheets("Printout").Range("I" & i).Value = ""
End If
Next j
'---- Category 4 ------
i = 6
For j = 28 To 36
If UserForm1.Controls("Checkbox" & j).Value = True Then
ThisWorkbook.Sheets("Printout").Range("M" & i).Value = Me.Controls("Checkbox" & j).Caption
i = i + 2
Else
ThisWorkbook.Sheets("Printout").Range("M" & i).Value = ""
End If
Next j
UserForm1.Hide
End Sub
Sub CommandButton2_Click()
Unload UserForm1
UserForm1.Show
End Sub
Sub CommandButton3_Click()
Unload UserForm1
End Sub
Sub NewCar_Click()
Dim LastRow As Integer
Dim i As Integer
Dim j As Integer
LastRow = WorksheetFunction.CountA(Sheets("Populate").Columns("D:D"))
'---- Count No of Checkbox
Dim Ctrl As MSForms.Control
Dim n As Integer
Dim cbcount As Long
For n = 0 To Me.Controls.Count - 1
If Left(UserForm1.Controls(n).Name, 8) = "CheckBox" Then
cbcount = cbcount + 1
End If
Next n
i = 2 '--- Preset counter i
For j = 1 To cbcount
UserForm1.Controls("Checkbox" & j).Caption = ThisWorkbook.Sheets("Populate").Cells(i, 4).Value
i = i + 1
If i > LastRow And i < (cbcount / 4) Then
UserForm1.Controls("Checkbox" & j).Caption = ""
End If
If i > LastRow And i > (cbcount / 4 + 1) Then
i = 2
End If
Next j
End Sub
Sub UsedCar_Click()
Dim LastRow As Integer
Dim i As Integer
Dim j As Integer
LastRow = WorksheetFunction.CountA(Sheets("Populate").Columns("D:D"))
'---- Count No of Checkbox
Dim Ctrl As MSForms.Control
Dim n As Integer
Dim cbcount As Long
For n = 0 To Me.Controls.Count - 1
If Left(Me.Controls(n).Name, 8) = "CheckBox" Then
cbcount = cbcount + 1
End If
Next n
i = 2 '--- Preset counter i
For j = 1 To cbcount
UserForm1.Controls("Checkbox" & j).Caption = ThisWorkbook.Sheets("Populate").Cells(i, 8).Value
i = i + 1
If i > LastRow And i < (cbcount / 4) Then
UserForm1.Controls("Checkbox" & j).Caption = ""
End If
If i > LastRow And i > (cbcount / 4 + 1) Then
i = 2
End If
Next j
End Sub
Sub UserForm_Initialize()
Call PopulateComboBox
'----- Rename Frame Boxes Caption
Dim k As Integer, nc As Integer
nc = 1
For k = 2 To 5
Me.Controls("Frame" & k).Caption = ThisWorkbook.Sheets("Printout").Cells(5, nc)
nc = nc + 4
Next k
'--------------------------------------------------
Dim LastRow As Integer
Dim i As Integer
Dim j As Integer
LastRow = WorksheetFunction.CountA(ThisWorkbook.Sheets("Populate").Columns("D:D"))
'---- Count No of Checkbox
Dim Ctrl As MSForms.Control
Dim n As Integer
Dim cbcount As Long
For n = 0 To Me.Controls.Count - 1
If Left(Me.Controls(n).Name, 8) = "CheckBox" Then
cbcount = cbcount + 1
End If
Next n
i = 2 '--- Preset counter i
For j = 1 To cbcount
UserForm1.Controls("Checkbox" & j).Caption = ThisWorkbook.Sheets("Populate").Cells(i, 4).Value
i = i + 1
If i > LastRow And i < (cbcount / 4) Then
UserForm1.Controls("Checkbox" & j).Caption = ""
End If
If i > LastRow And i > (cbcount / 4 + 1) Then
i = 2
End If
Next j
End Sub
i have problem with my code in vba. I have to find how much similar numbers are in column 1 and 2, but for example Column 1 (6,6,34,21,23,40) and column2 (49,34,6,9,6,20) should write 3 cause there are pairs 6-6, 6-6 and 34-34. I know its messy explenation but i hope its understandable. My code so far is:
Sub totolotek()
Dim i As Integer
Dim x As Integer
Dim j As Integer
Dim liczba As Integer
Dim suma As Integer
Dim ileLosowan As Integer
Range("B2:C7").Interior.Color = RGB(135, 134, 125)
Range("B2:B7").Font.ColorIndex = 3
Range("C2:C7").Font.ColorIndex = 5
ileLosowan = 7
Randomize
For i = 2 To ileLosowan
x = Int(Rnd * (49) + 1)
Range("c" & i) = x
Next i
For i = 2 To 7
liczba = Range("c" & i)
For j = 2 To 7
liczbe = Range("b" & j)
If liczbe = liczba Then
Range("c" & i).Interior.Color = RGB(255, 255, 0)
Range("b" & j).Interior.Color = RGB(255, 255, 0)
suma = suma + 1
End If
Next j
Next i
Range("c" & 9) = suma
End Sub
Try this. I invested some time and I added some lines of code. The macro find all the number pairs.
Example (6,6,3,4,2) (2,3,6,9,0) --> results 3: (6-6, 3-3, 2-2)
Sub totolotek()
Dim i As Integer
Dim x As Integer
Dim j As Integer
Dim liczba As Integer
Dim suma As Integer
Dim ileLosowan As Integer
Dim str_B As String, str_C As String, str_BC As String
Dim max_rand As Long
ileLosowan = 20 ' you can change the number of element in the column
max_rand = 49 ' max randum number
start_row = 2 'start_row
str_BC = "B2:C" & ileLosowan
str_B = "B2:B" & ileLosowan
str_C = "C2:C" & ileLosowan
Range(str_BC).Interior.Color = RGB(135, 134, 125)
Range(str_B).Font.ColorIndex = 5
Range(str_C).Font.ColorIndex = 5
Randomize
For i = start_row To ileLosowan
x = Int(Rnd * (max_rand) + 1)
Range("C" & i) = x
Next i
For i = start_row To ileLosowan
x = Int(Rnd * (max_rand) + 1)
Range("B" & i) = x
Next i
liczba_array = Range("B" & start_row & ":B" & ileLosowan).Value2
liczbe_array = Range("C" & start_row & ":C" & ileLosowan).Value2
ReDim ID_array(1 To 1)
ID_array(1) = max_rand + 1
Count = 1
For i = 1 To UBound(liczba_array, 1)
For j = 1 To UBound(liczbe_array, 1)
For k = 1 To UBound(ID_array, 1)
If ID_array(k) = j Then
GoTo out
End If
Next k
If liczba_array(i, 1) = liczbe_array(j, 1) Then
Range("B" & (start_row + i - 1)).Interior.Color = RGB(150 + Count * 20, 0, 0)
Range("C" & (start_row + j - 1)).Interior.Color = RGB(150 + Count * 20, 0, 0)
suma = suma + 1
ID_array(Count) = j
Count = Count + 1
ReDim Preserve ID_array(1 To Count)
Exit For
End If
Next j
out:
Next i
Range("C" & ileLosowan + 2) = suma
End Sub
Something like this will do what you're after. Just incorporate it into you're code cause I don't really know what's going on there.
Dim i As Long, j As Long, arr As Variant, Total As Integer
For i = 2 To 7 'Rows to loop through in the column
Total = 0
arr = Split(Range("A" & i), ",") 'Split column A using the comma
For j = 0 To UBound(arr) 'Loop through the split values
If InStr(Range("B" & i), arr(j)) > 0 Then 'Find if value is within other column
Total = Total + 1 'If it is, add 1 to total
End If
Next j
Range("C" & i) = Total 'Write total to another column on same row
Next i
Or if you want a basic function for it that you can use in your sheet you can use this:
Public Function CountMatches(Cell As String, Rng As Range, Optional Delim As String)
Dim i As Long, j As Long, arr As Variant, Total As Integer
If Delim = "" Then Delim = ","
If Rng.Count > 1 Then
CountMatches = "Please choose 1 cell to compare to."
Exit Function
End If
Total = 0
arr = Split(Cell, Delim) 'Split column A using the comma
For j = 0 To UBound(arr) 'Loop through the split values
If InStr(Rng, arr(j)) > 0 Then 'Find if value is within other column
Total = Total + 1 'If it is, add 1 to total
End If
Next j
CountMatches = Total
End Function
Use it like =CountMatches(A1,B1,",")
I have a worksheet with over 60,000 rows and two columns. One column is transaction id, the other is item. I want to find the combinations of items in the orders. I found this vba code from someone with a similar problem
Sub basket()
On Error Resume Next
Dim ps(2, 20)
r = 3
tr = Cells(2, 1)
Item = Cells(2, 2) + "."
ps(1, 1) = 1
ps(2, 1) = Len(Item)
r2 = 2
r3 = 3
ic = 2
While Cells(r, 1) <> ""
If Cells(r, 1) <> tr Then
o = 1
k = 1
If ic > 1 Then
ic = ic - 1
While o = 1
For i = 1 To ic
entry = Mid(Item, ps(1, i), ps(2, i))
For j = i + k To ic
entry = entry & Mid(Item, ps(1, j), ps(2, j))
Cells(r2, 10) = tr
Cells(r2, 11) = entry
r2 = r2 + 1
x = 0
x = Application.WorksheetFunction.Match(entry, Range("e:e"), 0)
If x = 0 Then
x = r3
Cells(x, 5) = entry
r3 = r3 + 1
End If
Cells(x, 6) = Cells(x, 6) + 1
Next j
Next i
If k > Len(Item) - 1 Then o = 0
k = k + 1
Wend
End If
Item = ""
ic = 1
tr = Cells(r, 1)
End If
ps(1, ic) = Len(Item) + 1
ps(2, ic) = Len(Cells(r, 2)) + 1
Item = Item + Cells(r, 2) + "."
r = r + 1
ic = ic + 1
Wend
o = 1
k = 1
If ic > 1 Then
ic = ic - 1
While o = 1
For i = 1 To ic
entry = Mid(Item, ps(1, i), ps(2, i))
For j = i + k To ic
entry = entry & Mid(Item, ps(1, j), ps(2, j))
Cells(r2, 10) = tr
Cells(r2, 11) = entry
r2 = r2 + 1
x = 0
x = Application.WorksheetFunction.Match(entry, Range("e:e"), 0)
If x = 0 Then
x = r3
Cells(x, 5) = entry
r3 = r3 + 1
End If
Cells(x, 6) = Cells(x, 6) + 1
Next j
Next i
If k > Len(Item) - 1 Then o = 0
k = k + 1
Wend
End If
End Sub
Which worked when I ran the exact same code but with item categories. The problem is I'm running it with the item names and it's always crashing my Excel. Is there anyone that can guide me in the right direction?
this is the worksheet that doesn't work
this is what I get when I run it with the item category which works. They're the exact same data, one just has it as item category, and the other is item name.
Your code sample didn't do anything for me. It ran, but it didn't actually produce any kind of results at all. I did a quick Google search and found this.
Sub ListCombinations()
Dim col As New Collection
Dim c As Range, sht As Worksheet, res
Dim i As Long, arr, numCols As Long
Set sht = ActiveSheet
'lists begin in A1, B1, C1, D1
For Each c In sht.Range("A2:B2").Cells
col.Add Application.Transpose(sht.Range(c, c.End(xlDown)))
numCols = numCols + 1
Next c
res = Combine(col, "~~")
For i = 0 To UBound(res)
arr = Split(res(i), "~~")
sht.Range("H1").Offset(i, 0).Resize(1, numCols) = arr
Next i
End Sub
'create combinations from a collection of string arrays
Function Combine(col As Collection, SEP As String) As String()
Dim rv() As String
Dim pos() As Long, lengths() As Long, lbs() As Long, ubs() As Long
Dim t As Long, i As Long, n As Long, ub As Long
Dim numIn As Long, s As String, r As Long
numIn = col.Count
ReDim pos(1 To numIn)
ReDim lbs(1 To numIn)
ReDim ubs(1 To numIn)
ReDim lengths(1 To numIn)
t = 0
For i = 1 To numIn 'calculate # of combinations, and cache bounds/lengths
lbs(i) = LBound(col(i))
ubs(i) = UBound(col(i))
lengths(i) = (ubs(i) - lbs(i)) + 1
pos(i) = lbs(i)
t = IIf(t = 0, lengths(i), t * lengths(i))
Next i
ReDim rv(0 To t - 1) 'resize destination array
For n = 0 To (t - 1)
s = ""
For i = 1 To numIn
s = s & IIf(Len(s) > 0, SEP, "") & col(i)(pos(i)) 'build the string
Next i
rv(n) = s
For i = numIn To 1 Step -1
If pos(i) <> ubs(i) Then 'Not done all of this array yet...
pos(i) = pos(i) + 1 'Increment array index
For r = i + 1 To numIn 'Reset all the indexes
pos(r) = lbs(r) ' of the later arrays
Next r
Exit For
End If
Next i
Next n
Combine = rv
End Function
I found that from this link.
VBA - Write all possible combinations of 4 columns of data
I'm pretty sure if you do some more Googling, you can find other concepts that do pretty much the same thing.