Populate cells dynamically using a data connection in Excel - excel

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)

Related

Excel VBA Xlookup to reference worksheet containing certain date

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.

Getting Excel to Copy Data From One Cell to Another Depending on Date

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.

How do I run an Excel macro using values from different rows in a table?

I am writing an Excel macro to send emails from data in a spreadsheet. The data are in a table with each column providing different variables to create the email (to:, cc:, subject, attachments, etc).
I've got the macro to do what I want on one line of the table. My question is:
How do I scale the VBA code to work for each line of my table? I would like a hyperlink in each row to run the macro using the data in that row. Below is a small snippet of my code as an example:
Sub SendMail()
Dim xContractNumber As String
xContractNumber = Worksheets("Program Info").Range("L10").Value
End Sub
In the above example, I would like a hyperlink that runs the macro using the data in row 10 of the 'Program Info' sheet... And another button or link that would run the macro using data in row 11, and so on.
This answer attempts to combine many of the good answers and comments everyone has already given. The code below contains the functionality for both buttons and hyperlinks in a condensed way.
This code could go in one separate module:
Sub SendMailByButton()
SendMailForRow ActiveSheet.Buttons(Application.Caller).TopLeftCell.Row
End Sub
Sub SendMailForRow(ByVal r As Long)
If r < 1 Then Exit Sub 'Failsafe in case the row number is invalid
Dim xContractNumber As String, xValueInColumnM As String, xValueInColumnN As String
xContractNumber = ActiveSheet.Cells(r, 12).Value 'Col 12 is col "L"
xValueInColumnM = ActiveSheet.Cells(r, 13).Value
xValueInColumnN = ActiveSheet.Cells(r, 14).Value
'...etc.
'...Rest of code to send the actual email
End Sub
If buttons are used, SendMailByButton must be attached to every button's click event, and the above code would be enough.
If manually-added hyperlinks are used, the above code would need to be complemented with the following code in the sheet module for every sheet that uses the hyperlinks (in your case, you may only need to add this code in one sheet's module) ...
'This event is fired when the hyperlink is clicked
Private Sub Worksheet_FollowHyperlink(ByVal target As Hyperlink)
On Error Resume Next
SendMailForRow target.Range.Row
End Sub
Each manual hyperlink would have to link to the same cell it is sitting on (i.e. to a "Place in This Document" with the cell reference set to its current cell).
The problem remains that you will need to manually create a button or hyperlink for every row in your table, which can be a hassle, especially if there are many rows or if the number of rows can grow in future.
A way to circumvent this problem is to have an extra button at the top of the table that allows the user to automatically create the buttons and/or hyperlinks for each row of data (removing excess buttons or hyperlinks if the table shrinks in size). This may require that you post a separate question.
Another way to circumvent this problem is to forego buttons altogether and, instead, use Excel formulas with the native HYPERLINK function (replacing the "regular" links). In that case, the FollowHyperlink event handler above would no longer be needed, but you would need to add the following function (which can go in the same module where SendMailForRow would reside) ...
Function SendMailByHLink()
SendMailForRow ActiveCell.Row
Set SendMailByHLink = ActiveCell
End Function
You would then have to create an Excel formula such as the following in each row (in the column where you want the hyperlink) ...
=HYPERLINK("#SendMailByHLink()", "Send email")
Entering this formula will auto-generate a hyperlink in the cell, and it will tell Excel to execute function SendMailByHLink when the hyperlink is clicked. The function after the "#" is supposed to return the link's target, which is why SendMailByHLink returns ActiveCell to ensure that the focus remains on that cell (if you prefer, you could return another cell such as ActiveCell.Offset(, -2) so that the user is taken to the cell 2 columns back in the same row after the link is clicked). Before returning ActiveCell to Excel, SendMailByHLink will execute the email-sending code.
The nice thing about using a HYPERLINK formula is that you can easily copy/paste the formula up and down the all the rows in the table. Therefore, if your table increases in size, all the user has to do is to copy/paste the HYPERLINK formula into the new rows. The user can also delete excess HYPERLINK formulas if the table shrinks. It may even be possible to have Excel automatically copy the formula if the data is sitting on an official Excel table by using a calculated column.
Sorry for all the extra explanation. If you focus on the code blocks, you will see that the solution is simpler than it looks.

Record values from if Statement to current Cell Excel

I have created and excel spreed sheet.
Its pulls External data from a website into sheet 1.
On Sheet 2 Is where all my calculations are done.
In Sheet 2..
B1 is my Current Value that updates every hour,
M1 Is my current Time,
F1 Is my Current Time,
A4:A27 Is my Date Range,
B3:Y3 Is my Time Range,
And I'm using an if statement.=if(AND(F1=A4:A27), (M1=(B3:y3),B1,"")
If statement works fine. See image Below.
You can see on the 20-11-2017 there is a value under the 7 on today date. When the time changes to 8 the 7 value disappears. As see in the second image below. Because of the if statement not being true on the 7 value any longer.
I'm looking to store the history of the passed values.
How can i allow the if statement to save the values as a value instead of a reference that keeps changing.
You can use the Worksheet_Change Event with the following code. Basically it checks for the cell which is changed, if the cells changed is the "Current Value" cell then it will update the related date / time cell in the table.
Just double check your cell references in code below.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
'If the changed cell is the Current Value cell
If Target.Address = "$B$1" Then
Dim LastRow As Long
Dim DateRange As Range
Dim TimeRange As Range
'Can change the sheet name to what ever your final sheet will be called
With Target.Worksheet
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set TimeRange = .Range("B3:Y3").Find(Hour(.Range("K1")))
Set DateRange = .Range("A4:A" & LastRow).Find(.Range("F1"))
.Cells(DateRange.Row, TimeRange.Column).Value = .Range("$B$1").Value
End With
End If
End Sub
What you are looking for is TrackChanges. Excel has a native TrackChanges functions, that when needed, can export the history like you wanted, to a seperated sheet.
The downside is, however, you have to share it. More information can be found here:
Track changes in a Shared Workbook
Important: This article explains an older method of tracking changes using a "Shared Workbook." The Shared Workbook feature has many limitations and has been replaced by co-authoring. Co-authoring doesn't provide the ability to track changes. However, if you and others have the file open at the same time, you can see each other's selections and changes as they happen. Also, if the file is stored on the cloud, it's possible to view past versions so you can see each person's changes. Learn more about co-authoring.
If you want to go with VBA route, you can make a sub to copy every newly data added to the worksheet whenever it changes ( event-trigger sub )
Private Sub Worksheet_Change(ByVal Target As Range)
' Do stuff when worksheet changes
End Sub
An example is this: How do I get the old value of a changed cell in Excel VBA?

Excel Formula which places date/time in cell when data is entered in another cell in the same row

Hoping there is a way this can be done with a formula since I will be putting this on SharePoint as a shared workbook.
Column B contains Tasks, while Column E contains the Date and Time of when the Task was assigned. Is there a formula that would automatically enter the current date and time in Column E whenever someone entered data into column B?
Any assistance would be greatly appreciated.
Another way to do this is described below.
First, turn on iterative calculations on under File - Options - Formulas - Enable Iterative Calculation. Then set maximum iterations to 1000.
The 1000 iterations doesn't matter for this formula, but it stops excel getting stuck in an infinite loop for other circular references.
After doing this, use the following formula.
=If(D55="","",IF(C55="",NOW(),C55))
Once anything is typed into cell D55 (for this example) then C55 populates today's date and/or time depending on the cell format. This date/time will not change again even if new data is entered into cell C55 so it shows the date/time that the data was entered originally.
This is a circular reference formula so you will get a warning about it every time you open the workbook. Regardless, the formula works and is easy to use anywhere you would like in the worksheet.
This can be accomplished with a simple VBA function. Excel has support for a Worksheet Change Sub which can be programmed to put a date in a related column every time it fires.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 2 And Target.Offset(0, 3).Value = "" Then
Target.Offset(0, 3) = Format(Now(), "HH:MM:SS")
End If
End Sub
A quick explanation. The following "if" statement checks for two things: (1) if it is the second column that changed (Column B), and (2) if the cell 3 columns over (Column E) is currently empty.
If Target.Column = 2 And Target.Offset(0, 3).Value = "" Then
If both conditions are true, then it puts the date into the cell in Column E with the NOW() function.
Target.Offset(0, 3) = Format(Now(), "HH:MM:SS")
Range.Offset
Range.Column
Not sure if this works for cells with functions but I found this code elsewhere for single cell entries and modified it for my use. If done properly, you do not need to worry about entering a function in a cell or the file changing the dates to that day's date every time it is opened.
open Excel
press "Alt+F11"
Double-click on the worksheet that you want to apply the change to (listed on the left)
copy/paste the code below
adjust the Range(:) input to correspond to the column you will update
adjust the Offset(0,_) input to correspond to the column where you would like the date displayed (in the version below I am making updates to column D and I want the date displayed in column F, hence the input entry of "2" for 2 columns over from column D)
hit save
repeat steps above if there are other worksheets in your workbook that need the same code
you may have to change the number format of the column displaying the date to "General" and increase the column's width if it is displaying "####" after you make an updated entry
Copy/Paste Code below:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("D:D")) Is Nothing Then Exit Sub
Target.Offset(0, 2) = Date
End Sub
Good luck...
I'm afraid there is not such a function. You'll need a macro to acomplish this task.
You could do something like this in column E(remember to set custom format "dd/mm/yyyy hh:mm"):
=If(B1="";"";Now())
But it will change value everytime file opens.
You'll need save the value via macro.
You can use If function
Write in the cell where you want to input the date the following formula:
=IF(MODIFIED-CELLNUMBER<>"",IF(CELLNUMBER-WHERE-TO-INPUT-DATE="",NOW(),CELLNUMBER-WHERE-TO-INPUT-DATE),"")
Here is the solution that worked for me
=IF(H14<>"",NOW(),"")

Resources