VBA min start date displaying a number - excel

I have a column of dates in format dd/mm/yyyy and when I use the following code:
Sub DisplayDate()
MsgBox (WorksheetFunction.Min(Range("StartDate").EntireColumn))
End Sub
the result is 4442.7 which doesn't make sense as all entries in this column are either blank or in dd/mm/yyyy format. I'm trying to display the earliest date of the entire column. "StartDate" is the heading reference for that column, but this heading is in row 5 (there are four blank rows above it) It is working when the heading is not included i.e. taking from row 6 down, but I'm not sure how to code this using the name reference. I must use the name reference, not column number reference,

Using strings, VBA is confused and try guessing what you try extracting (as date). The returned value means "28/02/1912 16:48:00", but it is a wrong guess...
Sub DisplayDate()
MsgBox WorksheetFunction.Min(Range("StartDate").EntireColumn.Resize(Range("StartDate").rows.count - 1).Offset(1))
End Sub

Related

Excel VBA Module is inserting formula in entire column rather than single cell in row

I've looked through these forums extensively but haven't found a working solution to the strange issue I'm having.
Currently I have a spreadsheet where when a cell in column W is double clicked, a vba module is called to insert a string of text in column P of the same row that was clicked. This works with the following module:
Sub CommentPrinted()
ActiveCell.Offset(0, -7).Value = "NL at Nurses Station"
End Sub
This worked as intended but now I want to change this module slightly to insert that text string as well as the current day and month in brackets. In attempting to do so I changed the module to:
Sub CommentPrinted()
ActiveCell.Offset(0, -7).Formula = "=""NL at Nurses Station (""&DAY(TODAY())&""/""&MONTH(TODAY())&"")"""
End Sub
Although this does insert "NL at Nurses Station (day/month)" into column P as desired, rather than being inserted into a single cell, it is inserted into every row of my table in column P, overwriting any existing values.
Any suggestions as to how I can make sure the module only acts on column P of the row selected like the module did originally?
ADDITIONAL INFO
Strangely if I run the module a second time after it has inserted the value in all cells in column P, it works perfectly?
I have no clue why your entire column gets filled, the statement itself runs for the Activecell, and that can only be one cell at a time. Maybe you have a problem with cascading events, set a breakpoint to the routine and check with the debugger from where (and how often) it is called: View->Call Stack (Ctrl+L)
However, following remark: You shouldn't use a formula to add the date. A formula is recalculated whenever Excel thinks is should. If you open your file tomorrow, it will no longer display today's date but tomorrows. Instead, write the current date into the cell as a fixed string:
value = "NL at Nurses Station " & format(now, "dd/mm")

SumIfs VBA function not working properly in macro

I have a form that is supposed to show the total sum of different numeric values between two dates, a start date and a finish date. For this, I thought the best option would be to use the SumIfs WorkSheetFunction. However, after trying to code this, the function is not working properly. I am not sure of what is wrong. If I type the exact same formula on the worksheet that has the table with my sample data, it works perfectly.
So, the form I designed is the following:
A second label and textbox will be added for the finish (or end) date. However, I thought it would be better to do that once I get the code to work with a single date in the beginning. The textbox where the user will insert the start date is called tbxDate and the textbox that will show the resulting sum is called tbxBalance. The button that triggers the SumIfs functions is called cmdCalculate.
Also, the table that stores the data (which only has one row of data so far for testing purposes) is this one:
The table name is Sales, and the worksheet name is SalesWS. I thought the code should be pretty simple, unless there is something I am missing. What I did was:
Private Sub cmdCalculate_Click()
Set SalesRange = Worksheets("SalesWS").Range("Sales[TOTAL]")
Set DatesRange = Worksheets("SalesWS").Range("Sales[DATE]")
tbxBalance = Application.WorksheetFunction.SumIfs(SalesRange , DatesRange , ">=" & tbxDate)
End Sub
The issue is that the >= part of the criteria is failing. I only get proper results using only the greater than or less than conditions. For example, if I enter the date 09/08/2020 in the textbox the result in the balance textbox is 0, but if I enter the date 08/08/2020 or anything before it works. It just ignores the condition to sum the values if the date is equal to what is entered. It only works with dates greater or less than what the user inputs in the textbox, excluding the chosen date.
I already checked that the column with the dates in the table is formatted properly.
The version of your code given below should work provided your DATE range contains true dates and tbxDate contains a string VBA can recognise as a date.
Private Sub cmdCalculate_Click()
Dim Fun As Double
Set SalesRange = Worksheets("SalesWS").Range("Sales[TOTAL]")
Set DatesRange = Worksheets("SalesWS").Range("Sales[DATE]")
Fun = Application.WorksheetFunction.SumIfs(SalesRange, DatesRange, ">=" & CLng(CDate(tbxDate.Value)))
tbxBalance = Format(Fun, "#,##0.00")
End Sub
Remember that tbxBalance will cotnain a text string, not a number. Use Excel's NUMBERVALUE function to convert the formatted number you have in tbxBalance after the above code back to a number you can calculate with.

Applescript get all values of Excel column

I am trying to store all the values of an excel column in an array.
set rangeDate to {value of range "A14:A100"}
repeat with date in rangeDate
if (date as string is equal to "01/01/2001") then
log "It works"
end if
end repeat
In my Excel I do have an exact date of 01/01/2001 formatted in the specified columns. When I remove the range and it is just cell A14 (where the date is) it works. But when I include the range A14:A100 it doesn't work.
I am new to applescript, I guess that it doesn't store the values as array values and instead a string object? Any help would be appreciated
You have 4 issues :
1) value of range should not be between {}, but between ()
2) 'Date' is a reserved word in Applescript, so you should not use it as the variable in the loop. I replaced it with 'myDate'.
3) instead of converting your date to string to compare with "01/01/2001", it is quicker to keep comparing 2 dates, and then, compare with the date "01/01/2001"
4) I think it is a bug (at least with my Excel version), but the rangeDate variable is not a list of dates as expected, but for me a list of list : {{01/02/01},{02/02/01},………} Therefore, each member of 'rangeDate' is not a date, but a list made on one item which is a date ! I am not sure, but it could also be that range definition could be a list of ranges... So I am using item 1 of sub list.
Anyway, script bellow is working :
tell application "Microsoft Excel"
activate
tell active sheet of document 1
set rangeDate to (value of range "A14:A100")
repeat with mydate in rangeDate
set TheDate to item 1 of mydate
if TheDate = (date "lundi 1 janvier 2001 00:00:00") then
log "It works"
end if
end repeat
end tell
end tell
Quickly getting the values of a range of cells is great news! But even better is that you can fill in the values of a range by defining the value of that range. This is SO MUCH FASTER than doing it one cell at a time.
When I tried getting the value of a column (a range of cells), I received a list of lists. Each item in the list had only one value - that is the value of the cell.
To speed up complex operations, once you've got the list of values, take the process out of the "tell Excel" block and let AppleScript do the calculations. Then turn the result back into a list of lists and define the value of the range in Excel.
I had a problem reading ranges with some cells containing #VALUE! (failed formulas). I didn't find a solution on the Internet, so I thought it would be a good idea to share my solution here. Comments & improvement are surely welcome. I'm inclined to think there is a more straightforward solution to the problem than this. :)
Getting all values with value of range can lead to a problem messing up the output of the script. AppleScript doesn't consider a cell's content "#VALUE!" (= missing values) a value since it is, well, missing. Therefore the script doesn't include the cell's content in the list of values. This obviously messes up the cell order in the values list, since it has less items than the actual range has cells. In this situation it is quite impossible to return each value to its original cell in the workbook. Adding ”of ranges” to the code includes all cells with missing values solving the problem.
N.B. The values will be displayed as a one-dimensional array. Handling multi-column ranges requires more work. Nonetheless the missing values are included.
set celVals to (value of ranges of range "A1:A4")
E.g. {2.2.2022, 1.1.2011, missing value, 3.3.2033}
In order to return the values back to the workbook it is required to build back the list of lists. A missing value will be written to its cell as an empty string. Of course the original (failed) formula can be written instead, if needed.
N.B. again. This code applies to one column situation only. A little more is needed to put back a multi-column range. I'm sure you'll manage. :D
set returningCelVals to {}
repeat with i from 1 to count of celVals
set end of returningCelVals to {item i of celVals}
end repeat
set value of range ("A1:A4") to returningCelVals
EDIT: I knew there is a better solution. Here it is:
set celVals to string value of range "A1:A4"
String value gives a two-dimensional array of values and error messages of the range. String value gives also e.g. cell's currency symbols, so it is perhaps not suitable to all situations.

Dates Formatting in Excel

I have a column with many thousands of rows. The column is meant to be date and is of the format dd/mm/yyyy
But, when I try to do formulas based on the dates, something is clearly amiss.
For example, if you try to apply autofilter on the dates, some of them are grouped as a year with the expandable boxes while others appear as their own items.
For each record I tried a formula to parse it apart.=DATE(RIGHT(A2,4),MID(A2,4,2),LEFT(A2,2))
That did not help.
I also selected the column and switched it from general to date format
I really don't know how to ask the question any clearer. I can tell you that with a date of the format 1/11/2013 when I run =year(right(A1,4)) I get 1903 instead of 2013. When I run =date(right(A1,4),mid(A1,3,2),left(A1,2)) the formula returns 2/10/3192
It's very simple why your formulas doesn't work corectly. When yor're using somehting like this: RIGHT(A2,4), your value from A2 translates to 41579 for 1/11/2013 (Excel stores all dates as integers and all times as decimal fractions. You can read more here). Next formula should work well:
=DATE(RIGHT(TEXT(A2,"dd/mm/yyyy"),4),MID(TEXT(A2,"dd/mm/yyyy"),4,2),LEFT(TEXT(A2,"dd/mm/yyyy"),2))
Btw, if you'd like to get correct format for dates, you can add formula in some empty column (but before set date format for this column):
=A2*1
and drag it down. Then copy values from this temp column and paste them using "Paste special->Values" in colunm A (where should be date format as well)
Or you can use this simple macro:
Sub test()
With Range("A2:A100")
.NumberFormat = "dd/mm/yyyy"
.Value = .Value
End With
End Sub

Excel Date to String conversion

In a cell in Excel sheet I have a Date value like:
01/01/2010 14:30:00
I want to convert that Date to Text and also want the Text to look exactly like Date. So a Date value of 01/01/2010 14:30:00 should look like 01/01/2010 14:30:00 but internally it should be Text.
How can I do that in Excel?
=TEXT(A1,"DD/MM/YYYY hh:mm:ss")
(24 hour time)
=TEXT(A1,"DD/MM/YYYY hh:mm:ss AM/PM")
(standard time)
Here is a VBA approach:
Sub change()
toText Sheets(1).Range("A1:F20")
End Sub
Sub toText(target As Range)
Dim cell As Range
For Each cell In target
cell.Value = cell.Text
cell.NumberFormat = "#"
Next cell
End Sub
If you are looking for a solution without programming, the Question should be moved to SuperUser.
Here's another option. Use Excel's built in 'Text to Columns' wizard. It's found under the Data tab in Excel 2007.
If you have one column selected, the defaults for file type and delimiters should work, then it prompts you to change the data format of the column. Choosing text forces it to text format, to make sure that it's not stored as a date.
In some contexts using a ' character beforehand will work, but if you save to CSV and load again this is impossible.
'01/01/2010 14:30:00
Couldnt get the TEXT() formula to work
Easiest solution was to copy paste into Notepad and back into Excel with the column set to Text before pasting back
Or you can do the same with a formula like this
=DAY(A2)&"/"&MONTH(A2)&"/"&YEAR(A2)& " "&HOUR(B2)&":"&MINUTE(B2)&":"&SECOND(B2)
I have no idea about the year of publication of the question; it might be old now. So, I expect my answer to be more of a reference for future similar questions after my post.
I don't know if anybody out there has already given an answer similar to the one I am about to give, which might result -I think- being the simplest, most direct and most effective: If someone has already given it, I apologize, but I haven't seen it. Here, my answer using CStr instead of TEXT:
Asuming cell A1 contains a date, and using VBA code:
Dim strDate As String
'Convert to string the value contained in A1 (a date)
strDate = CStr([A1].Value)
You can, thereafter, manipulate it as any ordinary string using string functions (MID, LEFT, RIGHT, LEN, CONCATENATE (&), etc.)
If you are not using programming then do the following
(1) select the column
(2) right click and select Format Cells
(3) Select "Custom"
(4) Just Under "Type:" type dd/mm/yyyy hh:mm:ss
In Excel 2010, marg's answer only worked for some of the data I had in my spreadsheet (it was imported). The following solution worked on all data.
Sub change()
toText Selection
End Sub
Sub toText(target As range)
Dim cell As range
Dim txt As String
For Each cell In target
txt = cell.text
cell.NumberFormat = "#"
cell.Value2 = txt
Next cell
End Sub
As Text is localized it will break when trying you try to share your files over diffrent cultures. ÅÅÅÅ-MM-DD might work perfectly in sweden, is US, Germany or israel it will turn to shit.
The reasonable solution would be that english was accepted everywhere, but it's not.
Basically DON'T EVER use text as intended to format dates.
Here is how to create the date in ISO format. TEXT is used to ensure leading
=YEAR(A1)&"-"&TEXT(MONTH(A1);"00")&"-"&TEXT(DAY(A1);"00")
If you want it backwards, sideways or whatever, just change it.
https://www.reddit.com/r/ISO8601/comments/enhlp6/logic_of_the_different_date_time_systems_with/
The selected answer did not work for me as Excel was still not converting the text to date. Here is my solution.
Say that in the first column, A, you have data of the type 2016/03/25 21:20:00 but is stored as text. Then in column B write =DATEVALUE(A1) and in column C write =TIMEVALUE(A1).
Then in column D do =B1+C1 to add the numerical formats of the date and time.
Finally, copy the values from D into column E by right clicking in column E and select Paste Special -> Paste as Values.
Highlight the numerical values in column E and change the data type to date - I prefer using a custom date of the form YYYY-MM-DD HH:MM:SS.

Resources