Add missing row with Macro/Excel or Matlab - excel

I am really struggling with the simple task to write a Code to fill missing data in a measurement file. I've never coded before so it is quite difficult.
Problem description:
I have uploaded a picture with an example of the problem.
The source format is a .csv file with two columns, a timestamp (hh:mm:ss) and a value for each timestamp.
I created the row 'time value' in excel, which is displaying the timestamp as a number. (minute 1 = 1/1440 to minute 59 = 1439/1440).
In column D, I put the difference between two timesteps, which should be around 0.007 for a 1-minute step.
However, the problem is that some minutes are missing in the data throughout the column, sometimes only one minute and sometimes multiple.
Required Code
So what I need would be a Matlab Code, for instance, that would go through the timestamps or time values and identify missing minutes and write the values of its previous minute.
For example. Minute 6 missing? --> Write row for minute 6 and give it the value of minute 5.
I hope my problem is clear, otherwise, I am happy to explain more details.
--
Cheers
Alison :)
PS: The multiple files each have hundreds of thousands of data. That's why I would need an automated code :)
PICTURE:

I think you can do stuff like this :
Sub test()
lastrow = Worksheets("Inactive").Cells(Rows.Count, 1).End(xlUp).Row
For i = 3 To lastrow
If Format(TimeValue(CDate(Cells(i, 1).Value)) - TimeValue(CDate(Cells(i - 1, 1).Value)), "hh:mm:ss") > "00:01:00" Then
Rows(i).Insert
Cells(i, 1).Value = Format(TimeValue(CDate(Cells(i - 1, 1).Value) + "00:01:00"), "hh:mm:ss")
Cells(i, 2).Value = Cells(i - 1, 2).Value
End If
Next
End Sub
before
Output AFTER

Related

Checking if each number in a list is between multiple ranges

I have a list of numbers (that will be changed weekly) and I also have a list of ranges (that also change weekly). I need to check whether each number falls between each range.
Eg. My list of numbers on the left and my list of ranges on the right.
4 1 3
10 67 99
54 120 122
155
So what I need is to return a value if 4 falls between 1-3, then check if it falls between 67-99 and so on. Then return a value if 10 falls between 1-3 or 67-99 etc.
I have tried array and vba but I'm noob and I cant find much in the way of examples for this issue. I have had success with the following nested if;
=IF(OR(AND(G2>$L$2,G2<$M$2),AND(G2>$L$3,G2<$M$3),AND(G2>$L$4,G2<$M$4),G2,"")
=IF(OR(AND(G3>$L$2,G3<$M$2),AND(G3>$L$3,G3<$M$3),AND(G3>$L$4,G3<$M$4),G3,"")
However, once my number of ranges gets above a certain number it says i have too many characters.
Any help would be appreciated.
Regards,
Will.
So what I need is to return a value if 4 falls between 1-3, then check if it falls between 67-99 and so on. Then return a value if 10 falls between 1-3 or 67-99 etc.
If you want to match each value in col G with the list in L and M then, rearrange the G column values in a row as shown below so that you can get the entire view in one go.
Put this formula =(AND($N$1>L2,$N$1<M2)) in N2 and drag it down. Similarly put the formula =(AND($O$1>L2,$O$1<M2)) in O2 and pull it down and so on...
Thanks Siddarth. This works but the number of rows will be changing weekly and your method would be too tedious to do weekly.
Ended up working it out on my own. Pretty simple but took me forever!
Sub Subtract_Start()
Set rng1 = Range(Range("G2"), Range("G2").End(xlDown))
Set rng2 = Range(Range("L2"), Range("L2").End(xlDown))
For i = 2 To rng1.Rows.count
For j = 2 To rng2.Rows.count
If Cells(i, "G").Value > Cells(j, "L").Value Then
If Cells(i, "G").Value < Cells(j, "M").Value Then
Cells(i, "G").Copy Cells(i, "J")
End If
End If
Next j
Next i
End Sub

Calculate Total Hrs spent given intime and outtime using Excel vba

I have to calculate total hours spent
enter image description here
I have attached Excel(img) which shows the data format.
I have tried for some code as below"
For k = 2 To rowval:
InTime = Rows(k).Cells(1, 6).Value
OutTime = Rows(k).Cells(1, 7).Value
If InTime <> "" And OutTime <> "" Then
a = Val(InTime)
b = Val(OutTime)
time = b - a
For some values instead of getting 3.516666667 as output am getting 3 as output.
Can anybody please help me to get the appropriate output?
I don't think you need to use VBA for this calculation. You can just use a basic vba forumla in the Total Hrs Field as below.
=TEXT(G2-F2,"hh:mm")
If you want to do this in VBA then you can also use this formula in your VBA code with something like this:
time = TEXT(b-a,"hh:mm")
The trick here is including "hh:mm" which tells excel how to format the result.
Best

My for loop is too complex - Excel VBA

I'm still writing a program in Excel VBA, and I've been stuck on a specific problem for hours. I'm trying to determine if someone is available on a specific day, but the information I'm given is for when they aren't available.
So I'm trying to write a series of for loops to compare all of this information and put it into Excel. I'm facing the issue, though, of the fact that it's quite complex:
With ActiveSheet
' Check the ID_Array and Date_Array to see if any names match
For DateIndex = 0 To MinLimit
For IDIndex = 0 To ID_Number
'If (ID_Array(IDIndex, 0) = Date_Array(DateIndex, 0)) Then
' We're going to use our column not only as a match check, but as our way of ending the cycle
For colCounter = 2 To 6
' If the date in the doc and the date in the array match, continue
If (.Cells(1, colCounter).Text = Date_Array(DateIndex, 1)) Then
For rowCounter = 2 To 11
' If the time slot in this row matches up with the time slot in the array, and the name also matches up, mark the name to be unused in this row
If (.Cells(rowCounter, 1).Text = Date_Array(DateIndex, 2)) Then
If (ID_Array(IDIndex, 0) = Date_Array(DateIndex, 0)) Then
ID_Array(IDIndex, 3) = "1"
End If
End If
' If the name has not been flagged as 1, write it down in this row
If (ID_Array(IDIndex, 3) <> "1") Then
supahotstring = ", " + ID_Array(IDIndex, 1) + " " + ID_Array(IDIndex, 2)
.Cells(rowCounter, colCounter).Value = .Cells(rowCounter, colCounter).Text + supahotstring
End If
' If the name HAS been flagged as 1, unflag it for the next row, since it might need to be written there
If (ID_Array(IDIndex, 3) = "1") Then
ID_Array(IDIndex, 3) = "0"
End If
' Now that all names can be checked for availability again, move on to the next row in this column
Next
End If
Next
'End If
Next
Next
End With
Above is the series of for loops I'm using. for reference, I use SQL to draw in the data, so everything is organized by records.
Since the possible available dates are fixed, I use the values I have set up in my Excel doc as a comparison to the dates people have put in. Basically, if someone has marked a specific timeslot on a specific day, I want to flag the record with that name as "1" so that it doesn't get marked down in that row. Then, I see if the current name is marked as "1", apply the appropriate actions, unmark it as "1" so that it can be checked again later.
However, when I run the program, a variety of problems occur: sometimes, the program will freeze up and I'll be forced to end task (I save quite often these days). Other times, when I write, it will simply write the same names in the same order in every box.
I feel like this should be a relatively easy problem to fix, but at this point I need a second opinion. I need to talk it over with someone here who's willing to look at it, and perhaps even find a way to do this without using four for loops.
It's a fairly complex program, and if you need more code for reference then I'm willing to provide it. I've tried to comment this code enough that it's fairly easy to understand. I really appreciate any help you can give.
EDIT: I cannot provide an image of expected output, but I can describe it. Imagine John Doe is going to be available on the first day, after 9:00AM. The program simply writes his name, along with every else's names, eleven time in each box.

subtract 5 minutes from formated time and reformat answer with seconds [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
VBA Excel: Add one second to a time
I have an Excel spreadsheet with the time value formated as Custom 00"00". I would like to subtract 5 minutes from this value and format the answer as hh:mm:ss using Excel VBA. I have looked all over but have not found an answer. I tried using various time functions but am not having much luck. I am a new Excel VBA programmer. Any suggestions would be appreciated.
If the Cell holds a real date-time-value, you can go with something like this:
Cells(r, c).Value = DateAdd("n", -5, Cells(r, c).Value)
Cells(r, c).NumberFormat = "hh:mm:ss"
I have no idea what custom format 00"00" is supposed to do, but since you say you have "...spreadsheet with the time value..." I assume the underlying data is a Date/Time serial number.
If this is the case then
Dim cl as Range
Set cl = Range("YourCellAddress")
cl = cl - 5# / 1440# ' subtract 5 minutes
cl.NumberFormat = "hh:mm:ss" ' format

Excel: create sortable compound ID

All, I asked a question "Excel VBA: Sort, then Copy and Paste" and received two excellent answers. However, because I failed to provide sufficient user requirements, they won't work: I asked for a fix to the existing solution I created, instead of specifying the actual business need and seeing if anyone has a better way.
(sigh) Here goes:
My boss asked me to create a ss to log issues. He wants a compound ID that concatenates the "Assigned Date" with a number that indicates what number issue it is for that day only. A new day, the count must restart at 1. E.g.:
Assigned Issue Concatenated
Date & Count = ID
5/11/2011 & 1 = 5112011-1
5/11/2011 & 2 = 5112011-2
5/11/2011 & 3 = 5112011-3
5/12/2011 & 1 = 5122011-1
I solved this with a hidden column C that calculates =IF(D2<>D1,1,C1+1), thus calculating the Issue Count by incrementing the previous issue count if the assigned date in column D is the same as the previous date, and starting over at 1 when the date changes. Another column concatenates the assigned date and the issue count, and I have my issue ID.
Quick, easy, elegant, in, out, and done. Right? But when I delivered the ss, he pointed out that if you (that is, he) sorts any part of the spreadsheet, the issue ID goes out of sequence. Of course---each formula isn't referencing the previous date in sequence if the rows are sorted out of Assigned Date order.
My immediate thought, which prompted my previous question, was to first re-sort the Assigned Date order correctly, then copy and paste the value of the calculated Issue Count to lock it in, and thus preserve the concatenated ID.
The only other way I can see to do this (in VBA, natch) is to:
evaluate all the dates in the Assigned Date column
evaluate all the numbers in the Issue Count column
calculate the latest sequential Issue Count for an a new item assigned on a given Assigned Date
Assign that sequential Issue Count to the new item
It'd be nice to then place the cursor into the next cell that the user would ordinarily go to, which would be the one right adjacent to the just-entered Assigned Date; however, that isn't necessary
That would avoid the need to re-sort the physical ss. However, besides a hazy guess that this would involve VLOOKUP, I got nothing. I couldn't find anything through searching.
Can anyone help? Or suggest a place to go? Thanks!!!
Sounds like you just want to automate a Paste Special action. The following replaces the formulas in a1:a100 with their calculated values:
Set src = ActiveSheet.Range("a1:a100")
src.Copy
src.Select
Selection.PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, _
SkipBlanks:=False, _
Transpose:=False
I think the formula =IF(D2<>D1,1,C1+1) could be improved as this relies on dates being in order. The following will preserve the count for any order that is sorted
Assume
ColA ColB ColC
Row1 Assigned_Date Issue Count Concatenate
Row2 05/11/2011 =COUNTIF($A$1:A2,A2) =TEXT(A2,"ddmmyyyy")&"-"&B2
Row3 05/11/2011 =COUNTIF($A$1:A3,A3) =TEXT(A3,"ddmmyyyy")&"-"&B3
Row4 05/12/2011 =COUNTIF($A$1:A4,A4) =TEXT(A4,"ddmmyyyy")&"-"&B4
Row5 05/11/2011 =COUNTIF($A$1:A5,A5) =TEXT(A5,"ddmmyyyy")&"-"&B5
Essentially enter B2 and C2 formulae and drag down. You might need to swap ddmmyyyy to mmddyyyy as we use dates first rather than months :)
Also, note the locking of the first part of the range only using $ - $A$1:Ax
This works perfectly for your current question but does not work if the Issue Count is assigned in time order per date.
How about using a procedure? Just click a button to add the next entry.
I've assumed that the entries will be given today's date and that the sheet layout is:
Rows: 1 = Title / 2 = left blank / 3 = Headings of the data block
Columns: A = Date / B = Issue Count / C = Combined ID / D etc = other data
Sub AddEntry()
Dim iDayRef As Long, iNumRows As Long, n As Long
With Range("A3")
iNumRows = .CurrentRegion.Rows.Count
For n = 2 To iNumRows
If .Cells(n, 1).Value = Date Then
If .Cells(n, 2).Value > iDayRef Then iDayRef = .Cells(n, 2).Value
End If
Next
.Cells(iNumRows + 1, 1).Value = Date
.Cells(iNumRows + 1, 2).Value = iDayRef + 1
.Cells(iNumRows + 1, 3).Value = Format(Date, "mm/dd/yyyy") & " - " & iDayRef + 1
.Cells(iNumRows + 1, 4).Select
End With
End Sub
And do you really need three columns for Date, Count, and Combined ID? If you went with a
yyyy/mm/dd - xx
ID format, one column could replace all three, and you could easily sort on it.

Resources