Still a novice at VBA but learning and ran up what i believe is a pretty advanced request.
I have a workbook our managers use that has 5 worksheets created each month. Each one is suffixed by the current Month_YYYY. I am trying to add an Xlookup to the worksheet whose date is one month prior (same prefix) and fill down to the last row.
So in this example, in B2 of the Oasis_Detail_November_2022 worksheet I would have:
=IFERROR(XLOOKUP(A2,'Oasis_Detail_October_2022'!A:A,'Oasis_Detail_October_2022'!B:B),C2) In December, it would reference the November tab and so on.
Is it even possible to do this? If it helps, the order of the tabs are always the same and i'm always looking 5 back (this example I hid a column just for screenshot room).
This is my rudimentary code thusfar. Thanks for the help.
Sub Oasis_Detail_Formatting()
Rows(2).EntireRow.Delete
Columns("A").Cut
Columns("C").Insert
[A:A].Select
With Selection
.NumberFormat = "General"
.Value = .Value
End With
Columns("B").Insert
Range("B1").Value = ("Svc Rel Parent")
ActiveSheet.UsedRange.EntireColumn.AutoFit
End Sub
I tried to use a Dim Dt As String and Dt = Format(Date, "mmmm_yyyy") statement within the Xlookup code but everyway i formatted the function, i just kept getting a debug error.
Related
What I'm trying to do is create a journaling spreadsheet that records the time and date of the entry at the time its submitted from a UserForm then updates the calendar on a "Splash" worksheet to change the cell interior and font colors to show that a journal entry has been created for that specific day.
I have a module created to iterate through what has already been imported from older journal entries from earlier this year and I want to change the interior color and text color of a cell in the named ranges named after the months. In the image below, the month names are not in the named ranges, just the list of numbers.
Calendar View
Basically, I want to search the dates, select and change the color of the cell of those dates in the calendar (see above). I can make it through the first month named range just fine but when it becomes a new month, it gives me run-time error 91.
Sub updateCells()
Dim rCell As Range
Dim rRng As Range: Set rRng = Worksheets("Journals").Range("A2:A44")
Dim thisDate, thisMonth, thisDay
Dim thisMonthRange As Range
For Each rCell In rRng.Cells
thisDate = Split(rCell.Text, " ")(0)
thisMonth = MonthName(month(thisDate))
thisDay = day(thisDate)
Range(thisMonth).Find(what:=thisDay).Interior.ColorIndex = 10
Range(thisMonth).Find(what:=thisDay).Font.Color = vbWhite
Next rCell
I'm am relatively new to VBA so I don't understand what would be causing the run-time error.
This takes having named ranges that are the actual names of the month, e.g., "January" list of dates (1-31) are referenced by Range("January").
I would use the following code to highlight the "18" in my Range("May") for today's date (2022-05-18):
Sub markCurrentDate()
Cells.ClearFormats
Dim currentMonth As String
currentMonth = Format(Date, "mmmm")
Dim currentDay As Long
currentDay = Format(Date, "dd")
Dim foundDate As Range
Set foundDate = Range(currentMonth).Find(currentDay)
foundDate.Interior.ColorIndex = 27
End Sub
Since we can't tell what your source cell for the date you're referring is, based on the current post, I used Date rather than a reference to a cell. The reference can be updated through, similar to being able to use With foundDate to add multiple format changes.
I think the problem is likely to be that one of your named ranges does not cover the entire range of days. February surely doesn't, you're missing the 28th!
At any rate, as a consequence (and apparently only on the second turn (a Feb 28?)), you run into the Run-time error '91', because Range(thisMonth).Find(what:=thisDay) is resolving to Nothing instead of an expected Range object once you fail to find thisDay inside the named range.
Evidently, the code cannot execute Nothing.Interior.ColorIndex = 10.
If correct, your solution should be to double-check and fix the incorrect named ranges.
Incidentally, Range(thisMonth).Find(what:=thisDay) is also superfluous. For obvious reasons, each range simply starts at 1 and increments with 1. So we could simply use thisDay as the index. Instead of this:
Range(thisMonth).Find(what:=thisDay).Interior.ColorIndex = 10
Range(thisMonth).Find(what:=thisDay).Font.Color = vbWhite
Simply use this:
With Range(thisMonth).Cells(thisDay)
.Interior.ColorIndex = 10
.Font.Color = vbWhite
End With
Update: come to think of this, if you want to insist on using Range(thisMonth).Find(what:=thisDay), you should at the very least change the snippet to Range(thisMonth).Find(what:=thisDay, LookAt:=xlWhole).
Counterintuitively, Range.Find(...) seems to accept a partial match by default (xlPart) and it actually remembers the settings you used on your last find (in the same Excel 'session'). Also, it will not always start where you expect it to do (see further this documentation and this post: Using the .Find Function VBA - not returning the first value). E.g. a realistic error depending on your settings / active cell position might be that your code (and incidentally, also the code provided by Cyril) will change the formatting for a day 10, when in fact you were trying to change the formatting for a day 1.
I have a small tracker program I am building in Excel VBA. I have a userform that I keep up throughout the day, inputting my tasks/data via an 'Add' button. At the end of the day, I click the 'Post' button, and it saves the data to my worksheets where appropriate.
Thought I had it finished and working correctly, but now apparently my sub to select the correct column based on the day's date is not working, and I'm not sure why, as it had been working perfectly throughout development.
This piece is vital, as my other functions to post the day's data rely on this. I've read a lot of other posts about how to do this (selecting a column based on current date), but none have explained why mine isn't working. Trying to become a better coder, and not just a copy/paste coder, so thought I would try asking here. Copy/Paste usually gets me into these messes, where I'm using tools/functions that work, but I don't know why, and can't troubleshoot/debug on my own.
My total project involves 5 worksheets, but this sub should only involve 2 of them. "Tasks" and "Data Tracker", both of which have a row of dates.
Below is the sub in question.
Public Sub currentDate()
'sub to assign current date to global values
Set rng - Range("H2:HZ2")
Set myDate = rng.Find(What:=Int(Date), LookIn:=xlFormulas)
End Sub
If I step through it, Date is pulling the correct date, and xlFormulas shows a value of -4123 (I don't even know if that matters)..
(UPDATE) so apparently, this morning, it decided to work perfectly. facepalm Any clues?
(UPDATE) so, per usual, I try adding features as I fix something else, so this took a bit more researching to solve, but #Super-Symmetry pointed me in the right direction! As noted in a comment down below, I changed my date headers in the two sheets to be more of a "start date + n" situation. Although his suggestion of using xlValue instead of xlFormula was on the right track, Find. was still having trouble with date vs serial. Ultimately this is what I got to work:
Public Sub currentDate()
'sub to assign current date to global values
'load the date range
Set rng = Worksheets("Tasks").Range("H2:HZ2")
'load the values in the range
dateArray = Range("H2:HZ2").Value
Dim day As Variant 'object to load dateArray
Dim loc As Integer 'matches date with cell location
'converting the date to serial
For Each day In dateArray
day = CLng(day)
loc = loc + 1
If day = Date Then 'we found the right column
Set myDate = rng(loc)
'selects the correct cell
If ActiveSheet.name = "Data Tracker" Then 'adjust the row
Cells(myDate.Row + 3, myDate.Column).Select
Else 'sheet must be Tasks
Cells(myDate.Row + 2, myDate.Column).Select
End If
Exit Sub
End If
Next
End Sub
It's not elegant, but it works.. please feel free to educate me if you have any cleaner ways to do this!
Try changing Int(Date) to CLng(Date)
Public Sub currentDate()
'sub to assign current date to global values
Dim rng As Range, myDate As Range
Set rng = Range("H2:HZ2")
Set myDate = rng.Find(What:=CLng(Date), LookIn:=xlValues)
End Sub
Apologies in advance as this is my first time posting something on this site and am not the best at explain issues.
I have a spread sheet, this has production data such as meters daily, meters monthly etc. These values are updated by adding TAGS from a PLC using Rockwell VantagePoint Excel add-in (if your unfamiliar with this it shouldn't matter this part is not what I am struggling with)
I need I way to copy data from one cell to another cell on the same sheet at month end. Basically the Meters monthly field needs to copied into another cell at the end of the month to record meters run for that month. The monthly meters run resets back to 0 at the end of the month.
Basically I need to copy the value in J7 into the corresponding month in W column at the end of that month. If it could ignore the year that would be advantageous as I don't need it to keep the old values and would mean I just need one column.
I have some experience at MS-Excel, also VBA but mainly in MS-Access never in MS-Excel. If answers could be explained as simply and hands on as possible it would be appreciated.
After Googling the issue I came across this formula and changed the ranges to fit my sheet but Excel doesn't like it saying it contains an error
=QUERY( A1:B6; "select B where A =date """&TEXT(TODAY();"yyyy-mm-dd")&""" "; 0
Sorry again if I haven't explained myself properly.
If your workbook isn't guaranteed to be open at the end of each month I would update the value every time it gets opened, like(Should be placed in ThisWorkbook):
'Runs when you open the workbook
Private Sub Workbook_Open()
'Loops through U3 to the last used cell in that column
For Each c In Range(Cells(3, 21), Cells(Rows.Count, 21).End(xlUp))
'Applies the J7 value to the current month and exits the sub
If Month(c) = Month(Now) Then c.Offset(, 2).Value = [J7]: Exit Sub
Next c
End Sub
Also, not that it matters but, I would apply the following formula in U3:U14 to always get the correct dates:
=EOMONTH(DATE(YEAR(TODAY()),ROW()-2,15),0)
Okay, I'm still not super sure what the question is and I know more Access VBA than Excel VBA, but here's something that might help to find a solution.
You can make a check date function that returns a Boolean value:
Public Function EoMonthCheck() As Boolean
Dim eo_month As Date, today As Date
eo_month = Format(WorksheetFunction.EoMonth(Now(), 0), "yyyy-MM-dd")
today = Format(Now(), "yyyy-MM-dd")
If today = eo_month Then
EoMonthCheck = True
Else
EoMonthCheck = False
End If
End Function
And the,, to add a value to the "W" column, we might use something like this:
Public Function AppendValue(Optional target_cell As String = "J7")
''' This could be a subroutine, too, I guess, since we're not returning anything.
Dim i As Integer
''' Activate whatever sheet you want to work with
Worksheets("Sheet1").Activate
If EoMonthCheck() = True Then
''' Look up the bottom of the 'W' column and find the first non-empty cell
''' Add 1 to that cell to get you to the next cell (the first empty one).
i = Cells(Rows.Count, "W").End(xlUp).Row + 1
''' Set the value of that empty cell in the 'W' column to the value of 'J7'
''' which will happen after we evaluate whether it is the end of the month.
Cells(i, "W").Value = Range(target_cell).Value
End If
Then, you could maybe trigger that each time the workbook opens.
I have been learning VBA for a while but there is one issue that I have been facing that I was not able to figure it out until know.
I want to be able to name a column using VBA, so I can use it later it as a reference column (using INDEX function) in other cells/columns.
I know to how to name a column that is fixed. But that is not what I am looking for.
Example of my issue:
This month I am naming column D as TotalAmount.
The VBA code can be:
ActiveWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:="=Sheet1!C4"
I will be referring to that column in other cells using the INDEX function.
However, next month I will be adding a new column (let's say previous month sales) just before Column D. So the new column that I want to name as TotalAmount the next month will be column E as opposed to D.
I know that the Column naming should not change when adding a new column and Column E will automatically become the TotalAmount column. However, I cannot rely on it because the excel sheet is accessed by different people and everyone is doing his own calculations.
So I tried this as well (I am sure it is stupid but hey I am still a noob) but it did not work :(
Sub Macro4()
Range("D1").Select
'(I can select the desired cell each month using the search function)
Dim i As Integer
i = ActiveCell.Column
ActiveWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:="=Sheet1!Ci"
End sub
So I will be very grateful if anyone could help me or guide me on this subject.
'i' is a variable so you cannot use that in quotes. In quotes, its just 'i' and has no value. try ActiveWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:="=Sheet1!C" & i
Not sure if this will resolve your problem though
You can get VBA to find the cell for you:
Sub SetNamedRange()
Dim rng As Range
Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1:Z1").Find("TotalAmount")
ThisWorkbook.Names.Add Name:="TotalAmount", RefersToR1C1:=rng
End Sub
The code searches A1:Z1 for the text "Total Amount" and sets the named range to that cell
I am currently trying to handle a data connection in Excel and I would like to populate some cells dynamically as the data is periodically changing.
More precisely, I have an Excel worksheet which is updated every 3 minutes through an internet data connection -stock market updates- during a time window of, say, 8 hours. Every 3 minutes the content of a cell (a decimal number), say, B1 is updated.
I would like to know if it is possible to "record" every number B1 throughout the 8 hours in a column on my worksheet. 8*60/3=160, hence I would like to dynamically populate 160 cells with the content of cell B1.
If it is possible, I then would like to take the maximum out of these 160 cells (using the MAX(,) function), record that number in another column and plot the graph of the evolution of the value of B1 over the 8 hours time window. The idea is to do this on daily basis so that after a week or month I could be able to look at the worksheet and assess the market trends.
Following the answer and comments, I have tried to write some VBA subroutines but I am struggling to get them to actually work. Here is my code:
Dim RunTime As Date
Dim j As Integer
Sub CopyCell()
Sheets("test").Cells(j, 3) = Sheets("test").Range("B1").Value
j = j + 1
'If Time >= TimeSerial(20, 0, 0) Then'
Application.OnTime RunTime, "CopyCell()", , False
End If
End Sub
Sub Main()
MsgBox "Starting Macro"
j = 0
RunTime = Now + TimeValue("00:03:00")
Application.OnTime RunTime, "CopyCell()"
End Sub
For the meantime I trigger the Main() sub myself and expect to make it stop at 20:0:0 (8pm). When I trigger the Main() sub I get the message "CopyCell() is not available in this workbook", but I do have copied the above code in the ThisWorkbook tab in the VBA editor and I have enabled all macros. Note that if I run the CopyCell() sub alone, the content of cell B1 is copied to cell C1.
Can you help me figure out what is wrong in my code?
Thanks,
-David
Without your code it is difficult to give you code on how to do this exactly, but in basic terms you can do this pretty easily. Whenever your refresh is fired simply have VBA write the data to a separate worksheet or a database (preferably a database like Access because it works happily with Excel and you don't need to save the Excel workbook)