I'm trying to figure out how to get the total of Mondays in a month then multiply by working hours.
This is my example code it works but it counts wrong output:
If UCase(val) Like "EVERY MONDAY" Then
Dim numString As Integer
Dim strDays() As String
Dim wordCount As Long
numString = 2
strDays = VBA.Split(val, " ")
wordCount = UBound(strDays)
strWhEveryDay = ThisWorkbook.Sheets("Input").Cells(X, 4).Value
strWhEveryDay = strWhEveryDay * var_month
Debug.Print "Every = " & strWhEveryDay
Explanation:
It depends on the user if what they like to input in a TEXTBOX. However, the CALCULATION it depends on the date where the user input in TEXTBOX.
I have Textbox which is the target month where the user input the format of date like this:
**Jan-2023 or Feb-2023 **
I have a table like this:
Place this text in a table start in Column B Row 2:
**every Monday**
Place this text in a table Column D Row 4:
**1.2**
All I need is to get all the total of Mondays based on the given month and year. The calculation of the days in a table of "every Monday" once I change the text from "every Monday" to "every Tuesday" so the calculation will adjust or automatically knows where the calculation days start to end:
Example of expected calculation: every Monday (January 2023 = 5 Days) * 1.2 so, the expected result will be 5.
Note: use Debug.Print to see the result or output
So, using networkdays.intl() as suggested in my comment:
NETWORKDAYS.INTL($A$3,$A$33,"0111111",)
The result shown is 5, which is correct by inspection, for cells A3:A33 the long date format was used.
So multiplying by 1.2 is:
NETWORKDAYS.INTL($A$3,$A$33,"0111111",)*1.2
and 5 * 1.2 = 6
Also, the string "0111111" can be put in cell F5 and referred to so it is easier to edit.
The easiest way I know to recognise any day of the week is the following:
=WEEKDAY(B2,2)
The "2" means that weekdays are counted, starting with "Monday" as 1, "Tuesday" as 2, ...
So, if you want to know if your date is a Monday, you can use this formula:
=IF(WEEKDAY(B2,2)=1,...)
This can easily be translated into VBA, using a standard IF-clause.
Breaking my head over this, time to look for help :(
I have a sheet with raw data, as illustrated below.
I'd like to calculate the average duration per TestName (column A) between the 2 timestamps (B and C) in another sheet.
How can I do this in 1 formula?
Note 1: The correct answer is (done manually)
test1 = 26:41:23
test2 = 08:23:10
Note 2: 1 formula please, without adding extra columns to calculate the duration per each first
Note 3: I cannot change the format of the raw data
Note 4: ignore empty fields
Thank you!
Use a new Column D to calculate the difference between start and end date on each row:
=DATEVALUE(C2)+TIMEVALUE(C2) - (DATEVALUE(B2)+TIMEVALUE(B2))
Next calculate the average on test1 and test2
=AVERAGEIFS($D:$D, $A:$A, "test1")
=AVERAGEIFS($D:$D, $A:$A, "test2")
Note that I'm using a comma as separator, in some languages, other separators, like semicolon are needed to write the formulas properly.
Now format the view to display at least the days in addition to the time: "DD - hh:mm:ss". Going beyond 31 days is a bit difficult as the month will count up.
If you don't like the formatting, go with the raw number format and extract the information through a bit of math. If it shows for example 1,5 it means one and a half days. I hope you can handle converting decimals to hours, minutes and seconds. MOD(ulo) and Rounddown are going to be your friends. :-)
I routinely get data in a time field column on an Excel spreadsheet that I need to convert into basic numbers such as 6, 7, 8.
Here's an example of the mess I get:
(Note: I cannot change how the data is received)
Time
-------------------------------
8am
10am
9:00 am (no early birds please)
8:00
9 a.m Sharp
7:00 am
8am-2pm
9 am
8AM TO 3PM
08-10-2018 9am
7:30am, 8:30 am
Any
9am
8AM TO 3PM
Today thru sun
10:00 a.m.
I recently ran some code that would pull out all numbers from the cell, then remove everything except the first number and that's somewhat close but...
The perfect scenario would be code to output the desired numbers and if cell data wouldn't comply with the code intent (error), a message box would open allowing edits, or, the cell would be flagged with a color so I knew where to look. I end up with about 500 lines of these cells to ferret through. Any suggestions would be appreciated.
While you are considering text comprehension, here's a cheap and dirty VBA function that might get a fair chunk of your cases. I would implement this in combination with conditional formatting that highlights cells greater than or equal to one or zero. (My example screenshot has such formatting in place.)
Public Function GetDate(DateVal As String) As Date
Dim returnDate As Date ' Date to be returned
Dim cleanedDate As String ' Working string containing the candidate date
Dim wordIndex As Integer ' Counter for walking through the word array
Dim wordArray() As String ' Working string broken into words
' Initialize to zero date
returnDate = CDate(0)
If IsNumeric(DateVal) Then
' Handle dates already converted
returnDate = CDate(DateVal)
Else
' Eliminate spurious characters
cleanedDate = UCase(Replace(Replace(Replace(DateVal, ".", ""), ",", " "), "-", " "))
If IsDate(cleanedDate) Then
' If CDate can fix it, just do that.
returnDate = TimeValue(CDate(cleanedDate))
Else
wordArray() = Split(cleanedDate, " ")
If UBound(wordArray) > 0 Then
wordIndex = 0
' Look through each word and return the first time found
Do Until returnDate > 0 Or wordIndex = UBound(wordArray)
If IsDate(wordArray(wordIndex)) Then
returnDate = CDate(wordArray(wordIndex))
End If
wordIndex = wordIndex + 1
Loop
End If
End If
End If
GetDate = returnDate
End Function
Here is what I get with your sample data in column A and =PERSONAL.XLSB!GetDate(A1) (or equivalent) in column B:
Note that rows 4, 6, and 8 show time values. This is because Excel converted the values when I pasted your sample data in place. The function handles values that Excel automatically converts.
Fixing Row 5 in code could get tricky. You'll have to weigh that coding effort against the simple manual fix of deleting the space between 9 and a.m.
The code gets about 80% of your example cases. If the ratio holds for your overall data, you're looking at manually adjusting roughly 100 cells. If you're doing this regularly, consider further tweaking of the code. One last ditch effort might be to walk through the string from left to right character by character to see if you can find and build a time string.
...or, of course, you can use text comprehension as mentioned above. :-)
Good Luck!
I am using excel and i want to display a value to a certain number of significant figures.
I tried using the following equation
=ROUND(value,sigfigs-1-INT(LOG10(ABS(value))))
with value replaced by the number I am using and sigfigs replaced with the number of significant figures I want.
This formula works sometimes, but other times it doesn't.
For instance, the value 18.036, will change to 18, which has 2 significant figures. The way around this is to change the source formatting to retain 1 decimal place. But that can introduce an extra significant figure. For instance, if the result was 182 and then the decimal place made it change to 182.0, now I would have 4 sig figs instead of 3.
How do I get excel to set the number of sig figs for me so I don't have to figure it out manually?
The formula (A2 contains the value and B2 sigfigs)
=ROUND(A2/10^(INT(LOG10(A2))+1),B2)*10^(INT(LOG10(A2))+1)
may give you the number you want, say, in C2. But if the last digit is zero, then it will not be shown with a General format. You have then to apply a number format specific for that combination (value,sigfigs), and that is via VBA. The following should work. You have to pass three parameters (val,sigd,trg), trg is the target cell to format, where you already have the number you want.
Sub fmt(val As Range, sigd As Range, trg As Range)
Dim fmtstr As String, fmtstrfrac As String
Dim nint As Integer, nfrac As Integer
nint = Int(Log(val) / Log(10)) + 1
nfrac = sigd - nint
If (sigd - nint) > 0 Then
'fmtstrfrac = "." & WorksheetFunction.Rept("0", nfrac)
fmtstrfrac = "." & String(nfrac, "0")
Else
fmtstrfrac = ""
End If
'fmtstr = WorksheetFunction.Rept("0", nint) & fmtstrfrac
fmtstr = String(nint, "0") & fmtstrfrac
trg.NumberFormat = fmtstr
End Sub
If you don't mind having a string instead of a number, then you can get the format string (in, say, D2) as
=REPT("0",INT(LOG10(A2))+1)&IF(B2-(INT(LOG10(A2))+1)>0,"."&REPT("0",B2-(INT(LOG10(A2))+1)),"")
(this replicates the VBA code) and then use (in, say, E2)
=TEXT(C2,D2).
where cell C2 still has the formula above. You may use cell E2 for visualization purposes, and the number obtained in C2 for other math, if needed.
WARNING: crazy-long excel formula ahead
I was also looking to work with significant figures and I was unable to use VBA as the spreadsheets can't support them. I went to this question/answer and many other sites but all the answers don't seem to deal with all numbers all the time. I was interested in the accepted answer and it got close but as soon as my numbers were < 0.1 I got a #value! error. I'm sure I could have fixed it but I was already down a path and just pressed on.
Problem:
I needed to report a variable number of significant figures in positive and negative mode with numbers from 10^-5 to 10^5. Also, according to the client (and to purple math), if a value of 100 was supplied and was accurate to +/- 1 and we wish to present with 3 sig figs the answer should be '100.' so I included that as well.
Solution:
My solution is for an excel formula that returns the text value with required significant figures for positive and negative numbers.
It's long, but appears to generate the correct results according to my testing (outlined below) regardless of number and significant figures requested. I'm sure it can be simplified but that isn't currently in scope. If anyone wants to suggest a simplification, please leave me a comment!
=TEXT(IF(A1<0,"-","")&LEFT(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00"),sigfigs+1)*10^FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1),(""&(IF(OR(AND(FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1)+1=sigfigs,RIGHT(LEFT(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00"),sigfigs+1)*10^FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1),1)="0"),LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00"))<=sigfigs-1),"0.","#")&REPT("0",IF(sigfigs-1-(FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1))>0,sigfigs-1-(FLOOR(LOG10(TEXT(ABS(A1),"0."&REPT("0",sigfigs-1)&"E+00")),1)),0)))))
Note: I have a named range called "sigfigs" and my numbers start in cell A1
Test Results:
I've tested it against the wikipedia list of examples and my own examples so far in positive and negative. I've also tested with a few values that gave me issues early on and all seem to produce the correct results.
I've also tested with a few values that gave me issues early on and all seem to produce the correct results now.
3 Sig Figs Test
99.99 -> 100.
99.9 -> 99.9
100 -> 100.
101 -> 101
Notes:
Treating Negative Numbers
To Treat Negative Numbers, I have included a concatenation with a negative sign if less than 0 and use the absolute value for all other work.
Method of construction:
It was initially divided into about 6 columns in excel that performed the various steps and at the end I merged all of the steps into one formula above.
Use scientific notation, say if you have 180000 and you need 4 sigfigs the only way is to type as 1.800x10^5
I added to your formula so it also automatically displays the correct number of decimal places. In the formula below, replace the digit "2" with the number of decimal places that you want, which means you would need to make four replacements. Here is the updated formula:
=TEXT(ROUND(A1,2-1-INT(LOG10(ABS(A1)))),"0"&IF(INT(LOG10(ABS(ROUND(A1,2-1-INT(LOG10(ABS(A1)))))))<1,"."&REPT("0",2-1-INT(LOG10(ABS(ROUND(A1,2-1-INT(LOG10(ABS(A1)))))))),""))
For example, if cell A1 had the value =1/3000, which is 0.000333333.., the above formula as-written outputs 0.00033.
This is an old question, but I've modified sancho.s' VBA code so that it's a function that takes two arguments: 1) the number you want to display with appropriate sig figs (val), and 2) the number of sig figs (sigd). You can save this as an add-in function in excel for use as a normal function:
Public Function sigFig(val As Range, sigd As Range)
Dim nint As Integer
Dim nfrac As Integer
Dim raisedPower As Double
Dim roundVal As Double
Dim fmtstr As String
Dim fmtstrfrac As String
nint = Int(Log(val) / Log(10)) + 1
nfrac = sigd - nint
raisedPower = 10 ^ (nint)
roundVal = Round(val / raisedPower, sigd) * raisedPower
If (sigd - nint) > 0 Then
fmtstrfrac = "." & String(nfrac, "0")
Else
fmtstrfrac = ""
End If
If nint <= 0 Then
fmtstr = String(1, "0") & fmtstrfrac
Else
fmtstr = String(nint, "0") & fmtstrfrac
End If
sigFig = Format(roundVal, fmtstr)
End Function
It seems to work in all the use cases I've tried so far.
Rounding to significant digits is one thing... addressed above. Formatting to a specific number of digits is another... and I'll post it here for those of you trying to do what I was and ended up here (as I will likely do again in the future)...
Example to display four digits:
.
Use Home > Styles > Conditional Formatting
New Rule > Format only cells that contain
Cell Value > between > -10 > 10 > Format Number 3 decimal places
New Rule > Format only cells that contain
Cell Value > between > -100 > 100 > Format Number 2 decimal places
New Rule > Format only cells that contain
Cell Value > between > -1000 > 1000 > Format Number 1 decimal place
New Rule > Format only cells that contain
Cell Value > not between > -1000 > 1000 > Format Number 0 decimal places
.
Be sure these are in this order and check all of the "Stop If True" boxes.
The formula below works fine. The number of significant figures is set in the first text formula. 0.00 and 4 for 3sf, 0.0 and 3 for 2sf, 0.0000 and 6 for 5sf, etc.
=(LEFT((TEXT(A1,"0.00E+000")),4))*POWER(10,
(RIGHT((TEXT(A1,"0.00E+000")),4)))
The formula is valid for E+/-999, if you have a number beyond this increase the number of the last three zeros, and change the second 4 to the number of zeros +1.
Note that the values displayed are rounded to the significant figures, and should by used for display/output only. If you are doing further calcs, use the original value in A1 to avoid propagating minor errors.
As a very simple display measure, without having to use the rounding function, you can simply change the format of the number and remove 3 significant figures by adding a decimal point after the number.
I.e. #,###. would show the numbers in thousands. #,###.. shows the numbers in millions.
Hope this helps
You could try custom formatting instead.
Here's a crash course: https://support.office.com/en-nz/article/Create-a-custom-number-format-78f2a361-936b-4c03-8772-09fab54be7f4?ui=en-US&rs=en-NZ&ad=NZ.
For three significant figures, I type this in the custom type box:
[>100]##.0;[<=100]#,##0
You could try
=ROUND(value,sigfigs-(1+INT(LOG10(ABS(value)))))
value :: The number you wish to round.
sigfigs :: The number of significant figures you want to round to.
I have an Excel 2010 workbook which contains a cell with the value of, say, 9876:54:32 (manually entered) representing 9876 hours, 54 minutes and 32 seconds of, say, phone talk time.
Then I have a cell with the value of, say, 1000 (manually entered) representing 1000 calls.
I want to divide the values to get the average talk time of 592.615 minutes per call.
I'm doing a regular =A1/B1 and it gives me an error.
* EDITED *
Thanks Brain Webster for correcting my math. I mean 9.876 hours. But the point is that Excel gives me an error, not my manual math. Playing around with it I discovered that Excel is fine with me with values up to 9999:59:59. Once I try with 10000:00:00 and up, it doesn't recognize it as a time value.
I love these seemingly easy riddles, so here is my solution as a formula and as a VBA attempt:
my original:
= (LINKS(A38;FINDEN(":";A38)-1)/24)+ZEITWERT("0"&RECHTS(A38;LÄNGE(A38)-FINDEN(":";A38)+1))
translated:
= (LEFT(A38,FIND(":",A38)-1)/24)+TIMEVALUE("0"&RIGHT(A38,LEN(A38)-FIND(":",A38)+1))
This will get you the right value to a given 10k text of a time duration. You would only have to setup the format of the cell to [h]:mm:ss. Then those values will look the same, but one would be a string and the other a number - and that is a major difference ;)
In vba it looks much more easier, and once defined, you can use it as a worksheetfunction.
Public Function GetDurationValue(ByVal strInput As String) As Double
Dim arrResult As Variant
arrResult = Split(strInput, ":") 'saves you parsing
GetDurationValue = (arrResult(0) / 24) + _
TimeSerial(0, arrResult(1), arrResult(2))
End Function
A38 = "10971:12:14"
=GetDurationValue(A38)
=457.13349537037
You can use LEFT and RIGHT function to retreive parts of the time value and then sum and multiply these values by 60 [minutes] (resp. 3600 [hours]).
Something like this for the hours, minutes, seconds (A1 is the cell with time value):
B1=VALUE(LEFT(A1;FIND(":";A1)))*3600
B2=VALUE(LEFT(A1;FIND(":";A1; FIND(":";A1))))*60
B3=VALUE(LEFT(A1;FIND(":";A1; FIND(":";A1; FIND(":";A1)))))
Now you can sum that:
C1=SUM(B1;B2;B3)
Then divede by calls count (A2 is the cell with the calls count):
D1=C1/A2
Finally format it like time:
E1=TEXT(D1/(24*3600);"d \day\s hh:mm:ss")
BTW: I tried that in Excel 2013 and when I enter 111:22:33 into a cell it automatically converts to a time. So then I can divide it like you try...
It appears that hours > 10000 are not recognised as such by Excel. Therefore we need to introduce an IF() to see whether this is the case and determined the alternative formula for the case where hours >10000
=IF(ISERROR(FIND(":",A2)),A2/B2, <SCRIPT IN CASE OF >10000>)
<SCRIPT IN CASE OF >10000> will now be:
VALUE(LEFT(A2,FIND(":",A2)))/24+VALUE(LEFT(A2,FIND(":",A2, FIND(":",A2))))/(24*60)+VALUE(LEFT(A2,FIND(":",A2, FIND(":",A2,FIND(":",A2)))))*(24*60*60)
combine and enjoy!
Assuming you don't exceed 100,000 hours in A1, and you always display hours, minutes and seconds then this formula should suffice
=IFERROR(A1/B1,(LEFT(A1)*10000/24+RIGHT(A1,10))/B1)
format result cell as [h]:mm:ss to get the result as a time value
With 10971:12:14 in A1 and 1000 in B1 that should give a result of 10:58:16 [or format result cell as [m]:ss to get minutes and seconds like 658:16]
This version will work with any number of hours and with or without seconds
=IFERROR(A1/B1,(LEFT(A1,FIND(":",A1)-1)/24+RIGHT(A1&IF(COUNTIF(A1,":*:"),"",":00"),5)/60)/B1)