Read Wildcard As Asterisk - excel

I had a piece of code commissioned earlier this week (cheaper to have an expert write it than for me to spend a week trying to!). However, when putting it use I've hit a bit of a snag.
The macro looks at a name on one excel worksheet, matches it to a list of names and associated ID numbers on a different worksheet, then inserts the ID on the first worksheet. This was all fine until I started using it on real data.
Here's some sample data (all of this information is in one cell...):
WARHOL*, Andy
PETO, John F
D3 GRECO, Emilio -20th C
HASELTINE, William Stanley
D3 DALI, Salvador
D3 SOSNO, Sacha
WEGMAN**, WILLIAM
One asterisk means it's a print, two a photograph, D3 a sculpture, and nothing a painting.
When I run the code with this data, it sees * as a wildcard, and so will always insert the ID of the first variation of the artist in the sheet. What I need is a way for the macro to not read it as a wildcard.
I did some research, and found that inserting ~ before * negates the wildcard properties. How would I make my code do this? I've discovered the main issue of having code written by someone else... You might not understand it!
Here is the code:
Public Sub match_data()
'ctrl+r
On Error GoTo errh
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim r1, r2, i, exc As Long
Dim fp As Range
Sheets("Data").Activate
r1 = Cells(Rows.Count, "B").End(xlUp).Row
r2 = Sheets("List").Cells(Sheets("List").Rows.Count, "B").End(xlUp).Row
'MsgBox r1 & r2
exc = 0
For i = 2 To r1
If Range("B" & i).Value <> "" Then
With Sheets("List").Range("B2:B" & r2)
Set fp = .Find(Range("B" & i).Value, LookIn:=xlValues, lookat:=xlWhole)
If Not fp Is Nothing Then
Range("B" & i).Interior.Color = xlNone
Range("A" & i).Value = Sheets("List").Range("A" & fp.Row).Value
Else
Range("B" & i).Interior.Color = xlNone
Range("B" & i).Interior.Color = vbYellow
exc = exc + 1
End If
End With
End If
Next i
MsgBox "There are " & exc & " exceptions."
errh:
If Err.Number > 0 Then
MsgBox Err.Description
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Oh also, I would need to do this for the list of names and ID's wouldn't I? If so, that only needs doing once, so if you could give me a hint about that too, I'd be so grateful!
Thanks!
PS I know the system we are using at the moment absolutely sucks (definitely not 3rd form normalised!), but we are fast running out of time and money, and need to get our product up and running ASAP!
EDIT: To clarify, here is a pic of the spreadsheets I'm working with... Obviously in cells A14 and A15 I wanted the ID numbers 11 & 12 respectively

Here is one way to tell the stars from the planets:
Sub StaryNight()
Dim s As String, OneStar As String, TwoStar As String, ThreeStar As String
OneStar = "*"
TwoStar = "**"
ThreeStar = "***"
t = Range("A1").Text
ary = Split(t, ",")
s = ary(0)
If Right(s, 3) = ThreeStar Then
MsgBox "scupture"
Exit Sub
ElseIf Right(s, 2) = TwoStar Then
MsgBox "photograph"
Exit Sub
ElseIf Right(s, 1) = OneStar Then
MsgBox "print"
Exit Sub
End If
MsgBox "Painting"
End Sub

Okay, I have solved the problem! I had a play around with changing the variables in the Find and Replace box.
If I put ~* in both the find AND replace boxes, and uncheck Match entire cell contents, I can replace all of the * with ~* (really don't understand that but oh well!)
So I do this on the Data worksheet, but NOT on the List worksheet, run the macro as normal and the problem is solved!

Related

Copy Data from Cell A to B and convert to Number

The below code is copying the data fine, however the copy when then number is copied over is copied as text. Is there any way to copy it over as a number?
Worksheets(1).Range(destCol1 & LR & destCol2 & LR).cells(3).value = Split(srcRange(5).value)
I've tried recording a macro where I'd highlight the data and click the option "Convert text to number" but it's not recording the VBA for that part.
EDIT 1:
With Worksheets(1).Range(destCol1 & LR & destCol2 & LR)
.cells(1).value = srcRange(2).text
.cells(2).value = srcRange(1).value
.cells(3).value = CDbl(Split(srcRange(5).value)(1))
.cells(4).value = srcRange(6).value
End With
Untested:
Sub jdskfhs()
Worksheets(1).Range(destCol1 & LR & destCol2 & LR).Cells(3).Value = CDbl(Split(srcRange(5).Value))
End Sub
EDIT#1:
Here is what you need:
Sub jdskfhs2()
Worksheets(1).Range(destCol1 & LR & destCol2 & LR).Cells(3).Value = CDbl(Split(srcRange(5).Value)(1))
End Sub
This new code converts the second element of the Split()-generated array to a number.
After quite a bit of digging, I found another answer on these forums here
I would ideally like to have it all done it one line to reduce processing power as these pages can get quite large; unfortunately this was the best solution I could get.
EDIT:
Using the below code that I modified a bit, but it does work
Private Function TextToNumber(rng As Range)
LR = ActiveSheet.Range("C" & Rows.Count).End(xlUp).row
For R = LR To 3 Step -1
With rng.cells(R, 1)
.NumberFormat = "General"
.value = .value
End With
Next R
End Function

Find if two non-consecutive values are the same vba

I have one column of data with either "UP", "DOWN" or "" as values. I am trying to write code that states that for all rows, if the first cell is "UP" then check the next rows until I come to either "DOWN" or "UP", i.e. if the next row has a "" then check the next row until I come to either a "DOWN" or "UP".
I am very new to VBA, and have tried various options, but seem to only be able to bring back where there are consecutive "UP"s or "DOWNS" rather than where there is an "UP", a number of rows of "" and then another "UP".
This is my code:
Range("z1:z250").Select
Selection.ClearContents
For Row = 2 To 250
If Range("Y" & Row).Value = "UP" Then
For sRow = 3 To 250
If Range("Y" & Row + 1).Value = "UP" Then
Range("Z" & Row) = "MT-UP"
ElseIf Range("Y" & Row + 1).Value = "" Then
End If
Next
End If
Next
End Sub
I have tried to add code such as For Each c in Range (“Y3”:”Y250”) but this doesn't make it find the next UP, and makes it very slow. I have also tried GoTo next cell (although seem to understand this is frowned upon!) but this doesn't work either. Any help appreciated.
Not 100% clear if this is what you want but take a look...
Instead of nested loops I used a flag to mark when a second consecutive "UP" was found before encountering a "DOWN". From your description it seems there's no need to check for empty cells ("").
Sub MTTest()
Dim Row As Long
Dim MTRow As Long
Dim MTFlag As Boolean
Range("Z1:Z250").ClearContents
For Row = 2 To 250
If Range("Y" & Row).Value = "UP" Then
If MTFlag = True Then
Range("Z" & MTRow) = "MT-UP"
MTFlag = Flase
Else
MTFlag = True
MTRow = Row
End If
Else
If Range("Y" & Row).Value = "DOWN" Then MTFlag = False
End If
Next
End Sub

Issues counting strings in VBA Excel

Hi i am trying to create a macro that will loop through my worksheet and find a specific string of text. Once if has found that string i want it to look to the column next to it and if it says PoweredOn or PoweredOff then add 1 to a counter then display the number at the end.
in my excel i have column A as my virtual machines and in column B is the power state I have a loop setup to look for one virtual machine that is a template and is powered on but when i run my macro it prints it as 0 here is my code at the moment.
Dim POT As Integer
Dim POFFT As Integer
Sheets("tabvInfo").Select
Range("A2").Select
Do
If ActiveCell.Value = ("vCloud Cell Template") Then
If ActiveCell.Offset(0, 1).Value = ("PoweredOn") Then
POT = Selection.Cell.Count
Else
If ActiveCell.Offset(0, 1).Value = ("PoweredOff") Then
POFFT = Selection.Cell.Count
End If
End If
End If
ActiveCell.Offset(1, 0).Select
Loop Until IsEmpty(ActiveCell.Offset(1, 0))
MsgBox ("The number of powerered on VMs is " & POT)
MsgBox ("The number of powerered off VMs is " & POFFT)
Can anyone tell me why i am getting 0 as the result? I also need to make this look at other templates on my system while retaining the count of values would i need to create a do loop for each template or can i use an array to do this?
Try this instead
Sub Main()
Dim POT As Long
Dim POFFT As Long
Dim c As Range
For Each c In Sheets("tabvInfo").Range("A2:A" & Sheets("tabvInfo").Range("A" & Rows.Count).End(xlUp).Row)
If StrComp(c, "vCloud Cell Template", vbTextCompare) = 0 Then
If StrComp(c.Offset(0, 1), "PoweredOn", vbTextCompare) = 0 Then
POT = POT + 1
ElseIf StrComp(c.Offset(0, 1), "PoweredOff", vbTextCompare) = 0 Then
POFFT = POFFT + 1
End If
End If
Next
MsgBox ("The number of powerered on VMs is " & POT)
MsgBox ("The number of powerered off VMs is " & POFFT)
End Sub
It eliminates the .Select statement and .ActiveCell. It's a simple for loop that achieves what you want.
I am not sure you realize but you can achieve this using 2 very simple formulas for PoweredOn and Off
=COUNTIFS(A:A,"vCloud Cell Template",B:B, "PoweredOn")
=COUNTIFS(A:A,"vCloud Cell Template",B:B, "PoweredOFF")
Therefore to eliminate the need for using a loop you can
Sub NoLoop()
MsgBox "Powered ON: " & Evaluate("=COUNTIFS(A:A,""vCloud Cell Template"",B:B, ""PoweredOn"")")
MsgBox "Powered OFF: " & Evaluate("=COUNTIFS(A:A,""vCloud Cell Template"",B:B, ""PoweredOff"")")
End Sub

How to hide rows in VBA based on values in row, quickly

this is my first time using the site, so forgive me for any inept explaining. I have a working macro to hide/unhide rows based on content of the rows, I just want it to be faster. Using a check box, when the box is checked, all rows with an "x" in column D get unhidden, those without an "x" get hidden. Same thing happens when it is unchecked, except it references column C, not D.
Right now, this code works. It's just a little slower than I'd like, since I'm sharing this with a bunch of people. Any ideas for how to speed it up? I'm pretty darn new to VB (the internet is astoundingly wise and a good teacher), but that doesn't matter. I already improved the code - before it selected each row, then referenced the column, and it was awful. Any ideas to speed it up (preferably without moving the screen) would be great.
Thanks so much folks,
DS
Sub NewLuxCheck()
Dim x As Integer
NumRows = Range("A42", "A398").Rows.Count
Range("A42").Select
If ActiveSheet.Shapes("checkbox2").OLEFormat.Object.Value = 1 Then
For x = 42 To NumRows + 41 Step 1
If Worksheets("Base").Range("D" & x).Value = "x" Then
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = False
Else
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = True
End If
Next
Else
For x = 42 To NumRows + 41 Step 1
If Worksheets("Base").Range("C" & x).Value = "x" Then
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = False
Else
Worksheets("Base").Range(x & ":" & x).EntireRow.Hidden = True
End If
Next
End If
MsgBox ("Done")
End Sub
You could use array formula and let Excel to return array with row-numbers where 'x' value occures. It will be quicker but you'll have to reorganise your code and create separate functions etc.
Here example where array formula finds rows whre in column 'D' the cell has value 'x'. Then string of this row numbers is created in form of "A1,A5,A10" ...means 'x' was found in rows 1,5,10. And finally Range(rowsJoind).EntireRow.Hidden is used for all the rows to be hidden/un-hidden in one step.
For rows with value different then 'x' you'll have to use formula like '=IF({0}<>""x"", ROW({0}), -1)'.
Sub test()
Dim inputRange As Range
Dim lastRow As Long
Dim myFormula As String
Dim rowsJoined As String, i As Long
Dim result As Variant
With Worksheets("Base")
lastRow = .Range("D" & .Rows.Count).End(xlUp).Row
Set inputRange = .Columns("D").Resize(lastRow)
Application.ReferenceStyle = xlR1C1
myFormula = "=IF({0}=""x"", ROW({0}), -1)"
myFormula = VBA.Strings.Replace(myFormula, "{0}", inputRange.Address(ReferenceStyle:=xlR1C1))
result = Application.Evaluate(myFormula)
result = Application.Transpose(result)
Application.ReferenceStyle = xlA1
For i = LBound(result) To UBound(result)
If (result(i) > -1) Then
rowsJoined = rowsJoined & "A" & result(i) & IIf(i < UBound(result), ",", "")
End If
Next i
.Range(rowsJoined).EntireRow.Hidden = False
End With
End Sub

VBA - How do i output data to corresponding cell by checking name and emptycell?

Good Day,
really need some help here, im bad at VBA.
Had created a spreadsheet and recorded a macro to record checkin of staff. However, im having difficulties checking out with the corresponding users based on the name.
Could anyone help me out over here?
Thanks. Had attached the spreadsheet for your ref.
http://www.etechnopia.com/vish/Book1ss.xlsm
After much googling, This is what i did based on mikes solution
Dim name As String
Dim id As Integer
Dim checkin As Date
Dim checkout As Date
name = Range("d6").Value
id = Range("d7").Value
checkin = Now
Range("d10") = checkin
Help anyone? im my very best here.
firstly I recommend to use range names for the important cells of your sheet
D6 EmpName
D7 EmpNo
D10 ClockInTime
D11 ClockOutTime
H5..H11 DataTable
This will enable you to reference them by name instead of hardcoding their addresses (bad bad hardcoding :-/ )
Secondly, your [Button] must serve a dual purpose ... it has to decide if a user is clocked in or out and do different things
a hi-level META code, executed at pressing [Button4] could be
if user clocked in
write current time into ClockOutTime ' remark: this may be superfluous
find DataTable record (EmpName, ClockInTime)
write ClockOutTime into record (EmpName, ClockInTime)
erase EmpName, EmpID, ClockInTime, ClockOutTime
else
write current time into ClockInTime
find first blank record in DataTable
write EmpName, EmpID, ClockInTime into DataTable record
endif
How to decide if a user is clocked in? If many users are using the same sheet at the same time (meaning 5 emps go there, write in their names and clock in) you need to examine DataTable for the first record of EmpNane without a ClockOutTime - if found he/she is in and needs to be clocked out.
more later ...
OK ... sorry was interrupted by Lady Gaga concerto in Vienna/AT
so here's a full code for the button
Sub ButtonPressed()
Dim DB As Range, Idx As Integer
Set DB = Range("DataTable")
If Range("EmpName") = "" Or Range("EmpNo") = "" Then
MsgBox "Enter your name and ID before pressing the button", vbCritical + vbOKOnly, "missing input"
Exit Sub
End If
Idx = UserClockedIn()
If Idx <> 0 Then
DB(Idx, 4) = Date + Time()
DB(Idx, 5).Formula = "=" & DB(Idx, 4).Address(RowAbsolute:=False, ColumnAbsolute:=False) & "-" & DB(Idx, 3).Address(RowAbsolute:=False, ColumnAbsolute:=False)
DB(Idx, 5).NumberFormat = "[hh]:mm"
Range("EmpName") = ""
Range("EmpNo") = ""
Else
Idx = 2
Do While DB(Idx, 1) <> ""
Idx = Idx + 1
Loop
DB(Idx, 1) = Range("EmpName")
DB(Idx, 2) = Range("EmpNo")
DB(Idx, 3) = Date + Time()
End If
End Sub
Private Function UserClockedIn() As Integer
Dim DB As Range, Idx As Integer
Set DB = Range("DataTable")
UserClockedIn = 0
Idx = 2
Do While DB(Idx, 1) <> ""
If DB(Idx, 1) = Range("EmpName") And DB(Idx, 2) = Range("EmpNo") And DB(Idx, 4) = "" Then
UserClockedIn = Idx
Exit Function
End If
Idx = Idx + 1
Loop
End Function
#user502908: I have not documented it because I want you to find out exactly what it does and by that have a quick start into Excel-VBA :-) It doesn't do too much and there are some basic thechniques you will apply again & again if you go into VBA ... try to populate ranges "ClockInTime" and "ClockOutTime" :-)))
Book1ssNew.xlsm
have fun
I tried another simpler method which i could cope with
Sub yes()
Dim findId As Integer
Dim FirstAddress As String
Dim FindString As Integer
Dim Rng As Range
FindString = Range("d7").Value
If Trim(FindString) <> "" Then
With Sheets("Sheet1").Range("F1:J100")
Set Rng = .find(What:=FindString, _
After:=.Cells(1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False)
If Not Rng Is Nothing Then
Application.Goto Rng, True
FirstAddress = Rng.Address
Rng.Offset(0, 2).Value = Now()
Else
MsgBox "Nothing found"
End If
End With
End If
End Sub
Search entire spreadsheet given id, when id found, to indicate dynamically the checkin timing.

Resources