I have the below code which updates the relevant cell with the relevant value. Even though there is only 11, I was wondering if there is a much better way, for the purpose of helping to speed up the code & also incase there is ever a need to update 000's of cells.
Range("E1").Value = "Export Date"
Range("G1").Value = "Amended Start Date"
Range("H1").Value = "Ticket Age (Working Days)"
Range("J1").Value = "Overdue (1=Yes, 0=No)"
Range("U1").Value = "TicketEntity1"
Range("V1").Value = "TicketEntity2"
Range("W1").Value = "TicketEntity3"
Range("X1").Value = "TicketEntity4"
Range("Y1").Value = "TicketEntity5"
Range("Z1").Value = "TicketEntity6"
Sub Test()
Dim CurrentColumn As Long
Dim i As Long
CurrentColumn = 20
With wsTest
For i = 1 To 5 '<= Use the correct number according your requirements
.Cells(1, CurrentColumn + 1).Value = "TicketEntity" & i
CurrentColumn = CurrentColumn + 1
Next i
End With
End Sub
You can tighten it up with arrays to cover the contiguous cells.
Range("E1").Value = "Export Date"
Range("G1:H1").Value = array("Amended Start Date","Ticket Age (Working Days)")
Range("J1").Value = "Overdue (1=Yes, 0=No)"
Range("U1:Z1").Value = array("TicketEntity1","TicketEntity2","TicketEntity3", _
"TicketEntity4","TicketEntity5","TicketEntity6")
The TicketEntryx series could also be looped with the increment used as a suffix identifier.
Related
Hi I'm trying to create macro that will collect data from excell table. I create strings with similar names and ended by number. Please is there a way to loop over this strings ? This Code is not working, but will explain what I want to do.
Sub vzor()
Dim i As Integer
Dim input1, input2, input3, input4, input5, input6, input7, _
input8, input9, input10, input11, input12, input13, input14, _
input15, input16, input17, input18, input19, input20, input21, _
input22, input23, input24, input25, input26, input27, input28, _
input29, input30, input31, input32, input33, input34, input35, _
input36, input37, input38, input39, input40, input41, input42, _
input43, input44, input45, input46, input47, input48, input49, _
input50, input51, input52, input53, input54, input55, input56, _
input57, input58, input59, input60, input61, input62, input63, _
input64, input65, input66, input67 As String
For i = 2 To 67
If Range("B" & i).Value = "" Then
MsgBox "Please fill all required data (The cells with red fill)", vbOKOnly, "Missing data"
Range("B" & i).Select
Else
input & i = Range("B" & i).Value
End If
Next
This seems to be a perfect example for a dictionary
Option Explicit
Dim wb As Workbook, ws As Worksheet
Dim inputdict As Variant
Dim i As Long
Set inputdict = CreateObject("Scripting.Dictionary")
Set wb = ThisWorkbook 'Change if necessary
Set ws = wb.Sheets(1) 'Change if necessary
For i = 1 To 67
If ws.Cells(i, "B").Value = vbNullString Then
MsgBox "Please fill all required data (The cells with red fill)", vbOKOnly, "Missing data"
ws.Cells(i, "B").Select
Else
inputdict.Add i, ws.Cells(i, "B").Value
End If
Next i
This creates a dictionary (inputdict). The keys for this dictionary are integers defined by i ranging from 1 to 67. The values are the values in the cells as you specified in your code already.
I want to display the unemployment numbers for the specific year and race chosen by the user in a Userform. The userUnemployment will be static numbers that specific to certain conditions being met.
I have tried various If and Else, If and ElseIfs
Private Sub buttonOk_Click()
Dim year, race As String
Dim userUnemployment As String
'first find the year
If five Then
year = "2005"
ElseIf six Then
year = "2006"
ElseIf seven Then
year = "2007"
ElseIf eight Then
year = "2008"
ElseIf nine Then
year = "2009"
ElseIf ten Then
year = "2006"
ElseIf eleven Then
year = "2007"
ElseIf twelve Then
year = "2008"
ElseIf thirteen Then
year = "2009"
ElseIf fourteen Then
year = "2009"
ElseIf fifteen Then
year = "2006"
ElseIf sixteen Then
year = "2007"
ElseIf seventeen Then
year = "2008"
ElseIf eighteen Then
year = "2009"
End If
'now find the race for that year
If white Then
race = "white"
ElseIf black Then
race = "black"
ElseIf hispanic Then
race = "hispanic"
ElseIf asian Then
race = "asian"
End If
'now find the unemployment rate for the things specified
If year = "2005" & race = "white" Then
userUnemployment = "3.48"
ElseIf year = "2005" & race = "black" Then
userUnemployment = "5"
End If
MsgBox ("The year is " + year + ", and your race is " + userUnemployment + " " + race)
End Sub
I want the message to display the userUnemployment number specified. I only listed two choices because I have not found the other unemployment numbers I want to use yet. So as long as I can get it to work for those two then I can figure the rest out.
On a worksheet (I used Sheet1), create a table like this to hold your Unemployment Rates (Note that I only populated the values that you provided in your question):
You haven't shown what your userform looks like, but I assume it's got Option Buttons (radio buttons) for selecting the Year and the Race. In general, for this use case, a much cleaner solution would instead to use either Listboxes or Comboboxes. I decided to use Listboxes for this example. My userform looks like this:
And here is the full userform code. The UserForm_Initialize code populates the listboxes based on the table. Then the btnOK_Click() verifies that a Year and a Race have been selected and then finds the corresponding Unemployment Rate using a VLookup. It then outputs a MsgBox displaying the results:
Private Sub btnCancel_Click()
Unload Me
End Sub
Private Sub btnOK_Click()
Dim ws As Worksheet
Dim sRace As String
Dim lYear As Long
Dim lRaceCol As Long
Dim dUnemployment As Double
If Me.listYear.ListIndex = -1 Then
Me.listYear.SetFocus
MsgBox "Must select a year.", , "Error"
Exit Sub
End If
If Me.listRace.ListIndex = -1 Then
Me.listRace.SetFocus
MsgBox "Must select a race.", , "Error"
Exit Sub
End If
Set ws = ThisWorkbook.Worksheets(1)
lYear = Me.listYear.List(Me.listYear.ListIndex)
sRace = Me.listRace.List(Me.listRace.ListIndex)
dUnemployment = WorksheetFunction.VLookup(lYear, ws.Range("A1").CurrentRegion, WorksheetFunction.Match(sRace, ws.Rows(1), 0), False)
MsgBox "Year: " & lYear & Chr(10) & _
"Race: " & sRace & Chr(10) & _
"Unemployment Rate: " & dUnemployment
End Sub
Private Sub UserForm_Initialize()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(1)
Me.listYear.List = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp)).Value
Me.listRace.List = Application.Transpose(ws.Range("B1", ws.Cells(1, ws.Columns.Count).End(xlToLeft)).Value)
End Sub
Here's what it looks like in action:
I would use the msgbox like this: "Msgbox = "The year is " & year & " and your race is " & usereunemployment". This should display the message that you want to see....
I am new at vba and i want to make a macro for my daily routine. I successfully manage big part of them with your helps here, but i stuck a section.
What i want : I have a analysis file, and it comes with months, beginning of code i am asking how many months have in file and want to know which of them.
Sub Makro2()
howmanymonths= Application.InputBox(prompt:=ActiveSheet.Name & " how many months?", Type:=1)
For first = 1 To howmanymonths
nay = Application.InputBox(prompt:=ActiveSheet.Name & " First?", Type:=1)
Next first
End Sub
For example, there are totally 3 months and i answered first "3",then next question i replyed "7" so nay = 7, but when its in loop next will be "8" and "9"
but how i can create nay1, nay2,nay3 or till what last months.
Maybe a better solution? Please help me.
Here is the example for storing multiple data in dictionary and retrieve them using their key.
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
howmanymonths = Application.InputBox(prompt:=ActiveSheet.Name & " how many months?", Type:=1)
For first = 1 To howmanymonths
'Key is nay + numberindex
dict.Add "nay" & CStr(first), Application.InputBox(prompt:=ActiveSheet.Name & " First?", Type:=1)
Next first
MsgBox dict("nay1")
MsgBox dict("nay2")
MsgBox dict("nay3")
You cannot create new variables in a sub, while running the sub. And in general you do not need to. If you do not know how many units do you need, you may use an Array() or List() and add elements to them:
Sub TestMe()
Dim howManyMonths As Long
howManyMonths = Application.InputBox(prompt:=ActiveSheet.Name & Months count?",Type:=1)
Dim firstMonth As Long
firstMonth = Application.InputBox(prompt:=ActiveSheet.Name & " First?", Type:=1)
Dim someArray() As Long
Dim cnt As Long
ReDim someArray(howManyMonths - 1)
For cnt = LBound(someArray) To UBound(someArray)
someArray(cnt) = firstMonth + cnt
Next cnt
For cnt = LBound(someArray) To UBound(someArray)
MsgBox someArray(cnt)
Next cnt
End Sub
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
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.