please help me to know the error in this code [closed] - vba

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 days ago.
Improve this question
I would like to find out the error in this code. When applying the code using the IF and else rule, it applies to the first condition only and ignores the second condition, labs is a label.
Dim ww As Double, z As Double, s As Double, n As Double, j As Long
On Error Resume Next
ww = Application.WorksheetFunction.VLookup(ComboBox5.Value, ThisWorkbook.Sheets("users").Range("y2:z1000"), 2, 0)
With ListBox1
For j = 0 To ListBox1.ListCount - 1
If .List(j, 8) <> "" Then z = z + ListBox1.List(j, 6) * ww
s = s + ListBox1.List(j, 6) * ww
n = n + ListBox1.List(j, 6)
If ComboBox5.Value <> Labs2.Caption Or ComboBox5.Value <> Labs3.Caption Or ComboBox5.Value <> Labs4.Caption _
Or ComboBox5.Value <> Labs5.Caption Then
t11.Value = s
Else
t11.Value = z
End If
tx3.Value = n
Frame61.Visible = False
Labs7.Caption = ComboBox5.Value`your text`
Next j
End With
On Error GoTo 0
I want to modify this code to apply if and else rule.

I wrote my notes on your code in the comments:
Option Explicit
Sub Copy_Data_To_All_SubFiles()
Dim ww As Double
Dim z As Double
Dim s As Double
Dim n As Double
Dim j As Long
ww = Application.WorksheetFunction.VLookup(ComboBox5.Value, ThisWorkbook.Sheets(2).Range("y2:z1000"), 2, 0)
With ListBox1
For j = 0 To ListBox1.ListCount - 1
' > You might have a problem here, the way this is written _
it looks like you want "s = s..." and "n = n..." to be _
dependant on your ".List(j, 8) <> """ condition. _
Currently, these will always run. If you want them dependant, _
then write it like this:
'If .List(j, 8) <> "" Then
' z = z + ListBox1.List(j, 6) * ww
' s = s + ListBox1.List(j, 6) * ww
' n = n + ListBox1.List(j, 6)
'End if
If .List(j, 8) <> "" Then z = z + ListBox1.List(j, 6) * ww
s = s + ListBox1.List(j, 6) * ww
n = n + ListBox1.List(j, 6)
' > All these "Or"s mean, unless Labs 1, 2, 3 and 4 are the same, _
it will always return true, I'm not sure what your logic is _
but you either need "And"s or you need to change those _
"<>" signs to "=" signs
If ComboBox5.Value <> Labs2.Caption Or _
ComboBox5.Value <> Labs3.Caption Or _
ComboBox5.Value <> Labs4.Caption Or _
ComboBox5.Value <> Labs5.Caption Then
t11.Value = s
Else
t11.Value = z
End If
tx3.Value = n
Frame61.Visible = False
' Whats this? \/
Labs7.Caption = ComboBox5.Value `your text`
Next j
End With
End Sub

Related

Do until loop in vba

I written a vba where when i roll 6000 times dice, it will count the number of 1's rolled 2's rolled and so on until number of 6's
Private Sub CommandButton2_Click()
i = 6000
Do Until i < 0
n = Int(1 + Rnd * (6 - 1 + 1))
TextBox1.Text = Range("A1")
TextBox2.Text = Range("A2")
TextBox3.Text = Range("A3")
TextBox4.Text = Range("A4")
TextBox5.Text = Range("A5")
TextBox6.Text = Range("A6")
If n = 1 Then
Range("A1") = Range("A1") + n
ElseIf n = 2 Then
Range("A2") = Range("A2") + n / 2
ElseIf n = 3 Then
Range("A3") = Range("A3") + n / 3
ElseIf n = 4 Then
Range("A4") = Range("A4") + n / 4
ElseIf n = 5 Then
Range("A5") = Range("A5") + n / 5
ElseIf n = 6 Then
Range("A6") = Range("A6") + n / 6
End If
i = i - 1
Loop
End Sub
It works fine but the problem is it loads so slow, is there a way to fasten this code ?
Please try this code. It will give the result instantly.
Private Sub CommandButton2_Click()
Dim Arr(1 To 6) As Integer
Dim n As Integer ' random number: 1 to 6
Dim i As Long ' loop counter: turns
Randomize
For i = 1 To 6000
n = Int(1 + Rnd * (6 - 1 + 1))
Arr(n) = Arr(n) + 1
Next i
Range("A1").Resize(UBound(Arr)).Value = Application.Transpose(Arr)
For i = 1 To UBound(Arr)
Me.Controls("TextBox" & i).Value = Arr(i)
Next i
End Sub
The interaction between text boxes and worksheet cells isn't clear. It's easy to establish in any way you want.
Option Explicit
Private Sub CommandButton2_Click()
Dim i As Long
Dim n As Long
Dim results As Variant
results = Array(0, 0, 0, 0, 0, 0)
' read results from cells A1 - A6
For i = 1 To 6
results(i - 1) = Cells(1, i).Value
Next i
' roll the dice 6000 times
For i = 1 To 6000
n = Int(Rnd * 6)
results(n) = results(n) + 1
Next i
' write results to cells A1 - A6
For i = 1 To 6
Cells(1, i).Value = results(i - 1)
Next i
End Sub

Looping & Adding Values

I am trying to run a loop that looks for a value in a column and if it is found then another value is entered in the cell to the right of it.
m = 2
h = 1
Cells(m, 23).Select
Do
Cells(m, 23).Select
If ActiveCells <> " " Then
Cells(m, 24) = "Test"
End If
If InStr(Cells(m, 24).Text, "-") Then
h = h + 1
End If
m = m + 1
What I am finding is the script runs and does not seem to identify when the cell contains the word "Region". It is just skipping over as if the cell is empty.
Still pretty new to VBA's so this may or may not be an easy fix.
Thank you!
Try this:
Dim lr As Long
Dim m As Long: m = 2
Dim h As Long: h = 1
'Properly reference objects
With Sheets("YourActualSheetName")
'To add better control, identify boundaries of your loop,
'so find the last row that contain data.
lr = .Columns(23).Find(What:="*", _
After:=.Cells(1, 23), _
SearchDirection:=xlPrevious).Row
Do
'You can use one liner If's for some cases like this one
If .Cells(m, 23) = "Region" Then .Cells(m, 24) = "Type"
If InStr(.Cells(m, 24), "-") <> 0 Then h = h + 1
m = m + 1
Loop Until m > lr
End With
Edit1: As stated in the comments
Dim m As Long: m = 2
Dim h As Long: h = 1
With Sheets("YourActualSheetName")
Do
If .Cells(m, 23) = "Region" Then .Cells(m, 24) = "Type"
If InStr(.Cells(m, 24), "-") <> 0 Then h = h + 1
m = m + 1
Loop Until h = 9
End With

Find Copy and Paste in VBA macro

I am trying to write a macro which search data from one sheet and copy's to another.
But now I have a problem because I want to copy data between two searches and paste the whole data from multiple cells into one single cell.
For example in the above picture my macro:
SEARCH for "--------------" and "*****END OF RECORD"
COPIES everything in between , here example data in row 29 and 30 and from column A,B,C
PASTE all the data from multiple cells A29,B29,C29 and then A30,B30,C30 to single cell in sheet 2 say cell E2.
This pattern is reoccurring in the column A so I want to search for the next occurrence and do all the steps 1,2,3 and this time I will paste it in Sheet2 , cell E3.
Below is the code:
I am able to search my pattern but hard time in giving references to the cells in between those searched patterns and then copying all the data to ONE cell.
x = 2: y = 2: Z = 7000: m = 0: n = 0
Do
x = x + 1
If ThisWorkbook.Sheets("lic").Range("A" & x) = "---------------------" Then m = x
If ThisWorkbook.Sheets("lic").Range("A" & x) = "****** END OF RECORD" Then n = x
If (n > 0) Then
Do
For i = m To n
ThisWorkbook.Sheets("lic").Range("A" & i + 1).Copy
ThisWorkbook.Sheets("lic").Range("B" & i + 1).Copy
ThisWorkbook.Sheets("lic").Range("C" & i + 1).Copy
'If (n > 0) Then ThisWorkbook.Sheets("Sheet1").Range("E" & y) = ThisWorkbook.Sheets("lic").Range("A" & m + 1, "C" & n - 1): y = y + 1
'If (n > 0) Then ThisWorkbook.Sheets("Sheet1").Range("E" & y).Resize(CopyFrom.Rows.Count).Value = CopyFrom.Value: y = y + 1
Loop While Not x > Z
'Driver's Licence #:Driver's Licence #:Driver's Licence #:
x = 2: y = 2: Z = 7000: counter = 1
Do
x = x + 1
If ThisWorkbook.Sheets("lic").Range("A" & x) = "Driver's Licence #:" Then counter = counter + 1
If (counter = 2) Then ThisWorkbook.Sheets("Sheet1").Range("B" & y) = ThisWorkbook.Sheets("lic").Range("C" & x): y = y + 1: counter = 0
If x = Z Then Exit Sub
Loop
End Sub
Considering that the search is working correctly, about the copy thing you just need to do:
Sheet2.Range("E2").value = ThisWorkbook.Sheets("lic").Range("A" & i + 1).value & ";" & ThisWorkbook.Sheets("lic").Range("B" & i + 1).value & ";" & ThisWorkbook.Sheets("lic").Range("C" & i + 1).value
The result will be something like: AIR COO; L DAT; A
--------UPDATE---------
It was hard to understand your code, so I'm write a new one. Basically it's copy what it found on sheet1 to sheet2.
Sub Copy()
Dim count As Integer 'Counter of loops to the for
Dim Z As Integer 'Limit of (?)
Dim h As Integer 'Count the filled cells on sheet2
Dim y As Integer 'Counter the columns to be copied
Z = 7000
h = 1
'Assuming that the "----" will always be on the top, the code will start searching on the second row
'if it's not true, will be needed to validate this to.
For count = 2 To Z
If Sheet1.Cells(count, 1).Value <> "****** END OF RECORD" Then
If Sheet1.Cells(count, 1).Value <> "" Then
For y = 1 To 3 'In case you need to copy more columns just adjust this for.
Sheet2.Cells(h, 1).Value = Sheet2.Cells(h, 1).Value & Sheet1.Cells(count, y).Value
Next y
h = h + 1
End If
Else
MsgBox "END OF RECORD REACHED"
Exit Sub
End If
Next count
End Sub
Maybe I don't get the full idea but this might work for you.
I'm not at all sure what you want to see in the final output, so this is an educated guess:
Sub DenseCopyPasteFill ()
Dim wsFrom, wsTo As Worksheet
Dim ur As Range
Dim row, newRow As Integer
Dim dataOn As Boolean
Dim currentVal As String
dataOn = False
newRow = 3
Set wsFrom = Sheets("Sheet1")
Set wsTo = Sheets("Sheet2")
Set ur = wsFrom.UsedRange
For row = 1 To ur.Rows.Count
If wsFrom.Cells(row, 1).Value2 = "--------------" Then
dataOn = True
ElseIf wsFrom.Cells(row, 1).Value2 = "***** END OF RECORD" Then
newRow = newRow + 1
dataOn = False
ElseIf dataOn Then
currentVal = wsTo.Cells(newRow, 5).Value2
wsTo.Cells(newRow, 5).Value2 = currentVal & _
wsFrom.Cells(row, 1) & wsFrom.Cells(row, 2) & _
wsFrom.Cells(row, 3)
End If
Next row
End Sub
If you can get away without using the Windows clipboard, I would. Instead of copy/paste, here I demonstrated how you can simply add or append a value.
Add this sub:
Sub copy_range(rng As Range)
Dim str As String
str = rng.Cells(1).Value & rng.Cells(2).Value & rng.Cells(3).Value
Range("E" & Range("E" & Rows.Count).End(xlUp).Row + 1).Value = str
End Sub
Then your for loop should look like this:
For i = m To n
copy_range ThisWorkbook.Sheets("lic").Range("A" & i + 1 & ":C" & i + 1)
Next i

How do I make my program stop at a certain cell?

Hey guys I am new to VBA for excel and I am stuck with a problem.
I am trying to do some calculations for data input and I have to make my program stop displaying values on the worksheet before "Discrepancy" reaches any less than 5. This then should make both columns "Money" and "Discrepancy" stop together. After, the program will then start in another column (column "I1" for "Money2" and J1" for "Discrepancy2") when t=10 is inputted into the formula and the values are displayed in Columns I2 and J2 until till the end.
I'm not sure how to stop it before it reaches and also how to stop the other column simultaneously. I'm also not sure if it will continue for another t=10.
Any advice
Sub solver2()
Dim t As Double, v As Double, i As Integer
Dim rowG As Integer, rowH As Integer
i = 0: v = 0 'related to formuala
'Range("A3").Select
'Range("D3").Select
Range("G1").Value = "Money"
Range("H1").Value = "Discrepancy"
Range("G2").Select
For t = 0 To tf Step delta
ActiveCell.Offset(i, 0) = t
ActiveCell.Offset(i, 1) = v
v = v + delta * accel(t, v)
i = i + 1
Next t
rowG = ActiveSheet.Range("G2").End(xlDown).row
rowH = ActiveSheet.Range("H2").End(xlDown).row
For i = rowG To 1 Step -1
Dim val1 As Long
val1 = ActiveSheet.Range("G" & i).Value
If (val1 > 5) Then
ActiveSheet.Range("G" & i).EntireRow.Delete
End If
Next i
For i = rowH To 1 Step -1
Dim val2 As Long
val2 = ActiveSheet.Range("G" & i).Value
If (val2 > 5) Then
ActiveSheet.Range("G" & i).EntireRow.Delete
End If
Next i
For t = 0 To 10 Step delta 'This steps it per delta input
Range("I1").Value = "Money2"
Range("J1").Value = "Discrepancy2"
Range("I2").Select
ActiveCell.Offset(i, 0) = t
ActiveCell.Offset(i, 1) = v
v = v + delta * accel(t, v)
i = i + 1
Next t
End Sub
If you just need the cells to appear empty, you could use conditional formatting to set the text and background colors the same.
You might try a do while loop instead of a for loop to set the values in the first set:
Do While t <= tf And v < 5
ActiveCell.Offset(i, 0) = t
ActiveCell.Offset(i, 1) = v
v = v + Delta * accel(t, v)
i = i + 1
t = t + Delta
Loop
I'm not sure what you intended for the other columns, but this loop would leave t at the value you would use if you mean to continue where the first column left off

matching text EXACTLY within vba IF statement

I looked through the questions here and though there is a lot of stuff about matching similar strings with the instr function etc, there isn't much about exact matching.
I'm looping through a list of names classified by id where each id has its own corresponding benchmark. Unfortunately all the benchmark names are something along the lines of "Barclays" x Index where there are a ton of similar sounding names such as Barclays US Aggregate Index, Barclays Intermediate Us Aggregate Index etc... and just trying to match gives an output.. but the wrong data points. Here is my code for reference.. the issue is in 2nd elseif of the loop.
I was wondering if there is an easy method to resolve this.
For i = 1 To lastrow
Sheets(source).Activate
If source = "Historical" Then
If Range("A" & i).Value = delimit2 Then
benchmark_name = Sheets(source).Range("L" & i).Value
j = j + 10
name = Sheets(source).Range("A" & i + 1).Value
Sheets(output_sht).Range("D" & j - 3) = "Portfolio"
Sheets(output_sht).Range("E" & j - 3) = benchmark_name
ElseIf benchmark_name <> vbNullString _
And Range("A" & i).Value = benchmark_name Then
If IsNumeric(Sheets(source).Range("F" & i).Value) Then
Alt_return3 = Sheets(source).Range("F" & i).Value
If IsEmpty(Sheets(output_sht).Cells(j, col1)) Then
Sheets(output_sht).Cells(j, col1) = Alt_return3 / 100
End If
End If
If IsNumeric(Sheets(source).Range("G" & i).Value) Then
Alt_return5 = Sheets(source).Range("G" & i).Value
If IsEmpty(Sheets(output_sht).Cells(j + 1, col1)) Then
Sheets(output_sht).Cells(j + 1, col1) = Alt_return5 / 100
End If
End If
'
If IsNumeric(Sheets(source).Range("H" & i).Value) Then
Alt_returnINC = Sheets(source).Range("H" & i).Value
If IsEmpty(Sheets(output_sht).Cells(j + 2, col1)) Then
Sheets(output_sht).Cells(j + 2, col1) = Alt_returnINC / 100
End If
Sheets(output_sht).Range("D" & j & ":E" & j + 5).NumberFormat = "0.00%"
End If
Sheets(output_sht).Range("C" & j) = period
Sheets(output_sht).Range("C" & j + 1) = period2
Sheets(output_sht).Range("C" & j + 2) = period3
Else
End If
End If
Next i
Comment as answer because I cannot comment:
Aren't you looking for the Like operator?
And you should add to the top of your code: Option compare text
More info on the like operator
I know you are looking for an exact match. However you may want to consider trying a FuzzyMatch.
http://code.google.com/p/fast-vba-fuzzy-scoring-algorithm/source/browse/trunk/Fuzzy1
You can download/import this function to your workbook and then call it with the 2 strings/names you are comparing and it will return a score.
If I were you I'd loop through all the possible names and take the highest score.
Which in your case would be 100% if you are looking for an exact match.
This will add time to your procedure but it might help you.
===EDITED
========= Here is the code. Add this to your Module.
Option Explicit
Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
'To be placed in the Declarations area
'_____________________________________
Sub TestFuzzy()
Dim t As Long, a As Long, i As Long
t = GetTickCount
For i = 1 To 100000
a = Fuzzy("Sorin Sion", "Open Source")
Next
Debug.Print "Similarity score: " & a & "; " & i - 1 & " iterations took " & _
GetTickCount - t & " milliseconds"
End Sub
'TestFuzzy's result should look like:
'Similarity score: 0.3; 100000 iterations took 2094 milliseconds
'The test was done on an Intel processor at 3.2GHz
'_____________________________________
Public Function Fuzzy(ByVal s1 As String, ByVal s2 As String) As Single
Dim i As Integer, j As Integer, k As Integer, d1 As Integer, d2 As Integer, p As Integer
Dim c As String, a1 As String, a2 As String, f As Single, o As Single, w As Single
'
' ******* INPUT STRINGS CLEANSING *******
'
s1 = UCase(s1) 'input strings are converted to uppercase
d1 = Len(s1)
j = 1
For i = 1 To d1
c = Mid(s1, i, 1)
Select Case c
Case "0" To "9", "A" To "Z" 'filter the allowable characters
a1 = a1 & c 'a1 is what remains from s1 after filtering
j = j + 1
End Select
Next
If j = 1 Then Exit Function 'if s1 is empty after filtering
d1 = j - 1
s2 = UCase(s2)
d2 = Len(s2)
j = 1
For i = 1 To d2
c = Mid(s2, i, 1)
Select Case c
Case "0" To "9", "A" To "Z"
a2 = a2 & c
j = j + 1
End Select
Next
If j = 1 Then Exit Function
d2 = j - 1
k = d1
If d2 < d1 Then
'to prevent doubling the code below s1 must be made the shortest string,
'so we swap the variables
k = d2
d2 = d1
d1 = k
s1 = a2
s2 = a1
a1 = s1
a2 = s2
Else
s1 = a1
s2 = a2
End If
If k = 1 Then 'degenerate case, where the shortest string is just one character
If InStr(1, s2, s1, vbBinaryCompare) > 0 Then
Fuzzy = 1 / d2
Else
Fuzzy = 0
End If
Else '******* MAIN LOGIC HERE *******
i = 1
f = 0
o = 0
Do 'count the identical characters in s1 and s2 ("frequency analysis")
p = InStr(1, s2, Mid(s1, i, 1), vbBinaryCompare)
'search the character at position i from s1 in s2
If p > 0 Then 'found a matching character, at position p in s2
f = f + 1 'increment the frequency counter
s2 = Left(s2, p - 1) & "~" & Mid(s2, p + 1)
'replace the found character with one outside the allowable list
'(I used tilde here), to prevent re-finding
Do 'check the order of characters
If i >= k Then Exit Do 'no more characters to search
If Mid(s2, p + 1, 1) = Mid(s1, i + 1, 1) Then
'test if the next character is the same in the two strings
f = f + 1 'increment the frequency counter
o = o + 1 'increment the order counter
i = i + 1
p = p + 1
Else
Exit Do
End If
Loop
End If
If i >= k Then Exit Do
i = i + 1
Loop
If o > 0 Then o = o + 1 'if we got at least one match, adjust the order counter
'because two characters are required to define "order"
finish:
w = 2 'Weight of characters order match against characters frequency match;
'feel free to experiment, to get best matching results with your data.
'If only frequency is important, you can get rid of the second Do...Loop
'to significantly accelerate the code.
'By altering a bit the code above and the equation below you may get rid
'of the frequency parameter, since the order counter increments only for
'identical characters which are in the same order.
'However, I usually keep both parameters, since they offer maximum flexibility
'with a variety of data, and both should be maintained for this project
Fuzzy = (w * o + f) / (w + 1) / d2
End If
End Function
==================
So once you have it then just add something like this.
Dim strA, strB, hiScore(1 to 3), tempScore
With Thisworkbook.ActiveSheet
For a = 1 to .Usedrange.Rows.Count ' Scans Column 1
strA = .cells(a,1) ' Barclays Aggregate Index
For b = 1 to .usedrange.rows.count ' Compares Col 1 to Col 2
strB = .cells(b,2) ' Barclays Aggregate Other Index
tempScore = Fuzzy(strA, strB)
If tempScore > hiScore then
hiScore(1) = tempScore
hiScore(2) = a
hiScore(3) = b
End If
Next b
' Do your Action with the Best Match Here
If hiScore(1) = 1 then ' (100% - perfect match)
' Copies col 3 from the row that the best strB match was on
' to col 4 from the row strA was on
.Cells(a,4) = .Cells(hiScore(3),3)
End If
' ====
' Reset Variables
hiScore = ""
tempScore = ""
Next a
End with