I have 4 columns of data - B10:E(LastRow).
Coulmn 1 = Dates - Not needed
Coulmn 2 = Money - Not Needed
Coulmn 3 = Segments Sold - Needed
Column 4 = Segments Left - Needed
I am struggling to write the code for Column 4.
I have a fixed value of segments called from Cells(4, 3), which is 100 in this case, to start the if statement.
I know my below code is incorrect.
For k = 10 To LR1
If ws2.Cells(k, "D") = 0 Then
ws2.Cells(k, "E") = 100
ElseIf ws2.Cells(k, "D") > 0 Then
ws2.Cells(k, "E") = ws2.Cells(4, 3) - ws2.Cells(k, "D")
End If
Next k
Basically I want Cells 10: to the first value that is > 0 to equal 100.
Then I want the cells 11th, from the first value greater than 0, we shall say 3, to be 97, until the next value greater than 0, say 7, thus it will equals 90 and so on for the rest of the column.
I hope this is clear enough. I have attached an image, left one is what I currently get, right one is what I would like to achieve.
Left - What I get with the if function // Right - What I want to achieve
Related
I have data coming into Excel (from external source) that looks like:
**Column A** **Column B**
6/26/2017 null
Temperature 27
Pressure 5
6/27/2017 null
Temperature 29
Pressure 4
I would like to have it like this:
**Column A (Date)** **Column B (Temp)** **Column C (PSI)**
6/26/2017 27 5
6/27/2017 29 4
Since the data comes in via 'Refresh All', how can I take that and push it to columns like this?
If you are sure of the periodicity of your data, you may use the OFFSET function.
Add an auxiliary column with an crescent index;
fill the "column date" with =OFFSET($A$1; ($E2-1)*3; 0), where:
A1 refers to your first cell in your external data (6/26/2017)
E2 refers to your index, the cell where my function was applied being F2
If to be 'pushed' you would need something like VBA, though is possible with a formula (in C2, copied across to D2 and the pair copied down to suit):
=OFFSET(A2,1,1)
but that would then need to be converted to Values (eg with Paste Special) if the surplus column and rows are to be deleted. And this would not 'refresh' as easily as say a PivotTable.
Try working from the last date to the top.
Dim i As Long
With Worksheets(4)
For i = Application.Match(1E+99, .Range("A:A")) To 1 Step -3
.Cells(i, "C") = .Cells(i + 2, "B").Value
.Cells(i, "B") = .Cells(i + 1, "B").Value
.Cells(i + 1, "A").Resize(2, 1).EntireRow.Delete
Next i
.Cells(1, "A").EntireRow.Insert
.Cells(1, "A").Resize(1, 3) = Array("**Column A (Date)**", "Column B (Temp)", "**Column C (PSI)**")
End With
I am currently working on a traveling sales person problem in Excel. For this I need to generate two rows parallel to each other ( Row1 for row Row2 for column) and use INDEX MATCH MATCH to look up the distances between nodes and solve using solver in order to get the best sequence to minimize distance.
For example I have row0 of four nodes named [1][2][3][4].
Distance matrix
__[1][2][3][4]
[1] 0, 4, 5, 7
[2] 4, 0, 6, 2
[3] 5, 6, 0, 1
[4] 7, 2, 1, 0
It must take row 0 and using a macro to develop the following 2 rows
Row 1 [1][1][1][2][2][3]
Row 2 [2][3][4][3][4][4]
Then I can use the Index Match Match to automatically bring all the distances below in a third row:
Row 1 [1][1][1][2][2][3]
Row 2 [2][3][4][3][4][4]
Row 3 4, 5, 7, 6, 2, 1
Please I need help developing the macro to create row 1 an row 2. This should be able to account for any amount of nodes and not just the 4 listed in the example.
I got the answer for row 2. Sorry if it seems like a basic question but I am a noob at VBA and hoping to get better. Ill post when I have the answer for the next row.
Sub Macro1()
'
' Macro1 Macro
k = 5
i = 0
j = 0
rwar = Worksheets("Sheet1").Cells(13, 5).Value
For i = 3 To rwar + 1
rwar = rwar - 1
For j = 1 To rwar
Worksheets("Sheet1").Cells(16, k) = Worksheets("Sheet1").Cells(i, 5).Value
k = k + 1
Next j
Next i
'
End Sub
I have a question regarding indexing in excel. Is there a way if I define an range (in this case it will be G2:G19), can I return the row in which a specified value appears (in this case = 100)? This is the example I have:
Value
G2 = 0
G3 = 0
G4 = 0
G5 = 100
G6 = 100
G7 = 100
In this cause I want to return "4" because this is the first row with 100? Can this be done?
Thanks!
Like Doug mentioned in the comments, the easiest way to do this is with the match function. More info
=MATCH(100,G2:G7,0)
It returns a relative reference so you would end up with 4.
The third number determines what kind of match to look for. If you enter an integer in the first part then the third number should be 1 to look for values less than that, 0 to look for an exact match, and -1 to look for values greater than.
Assuming you have declared and opened the Excel object and you want to loop through column G.
startrow= 2
endrow = 19
counts = 0
Do While startrow <> endrow
val = objWorkbook.Sheets("nameofsheet_or_index").Cells.Item(startrow, "G").Value
If val = "100" Then
counts = counts + 1
Exit Do
End If
counts = counts + 1
startrow = startrow + 1
Loop
I have an Excel file with several columns in it and many rows. One column, say A has ID numbers. Another column, say G has prices. Column A has repeating ID numbers, however not all numbers repeat the same amount of times. Sometimes just once, other times 2, 3 or several times. Each column G for that row has a unique price.
Basically, I need to average those prices for a given ID in column A. If each ID was repeated the same number of times, this would be quite simple, but because they are not I have to manually do my average calculation for each grouping. Since my spreadsheet has many many rows, this is taking forever.
Here is an example (column H is the average that I am currently calculating manually):
A ... G H
1 1234 3.00 3.50
2 1234 4.00
3 3456 2.25 3.98
4 3456 4.54
5 3456 5.15
11 8890 0.70 0.95
13 8890 1.20
...
So in the above example, the average price for ID# 1234 would be 3.50. Likewise, the average price for ID# 3456 would be 3.98 and for #8890 would be 0.95.
NOTICE how rows are missing between row 5 and 11, and row 12 is missing too? That is because they are filtered out for some other reason. I need to exclude those hidden rows from my calculations and only calculate the average for the rows visible.
Im trying to write a VBA script that will automatically calculate this, then print that average value for each ID in column H.
Here is some code I have considered:
Sub calcAvg()
Dim rng As Range
Set rng = Range("sheet1!A1:A200003")
For Each Val In rng
Count = 0
V = Val.Value '''V is set equal to the value within the range
If Val.Value = V Then
Sum = Sum + G.Value
V = rng.Offset(1, 0) '''go to next row
Count = Count + 1
Else
'''V = Val.Value '''set value in this cell equal to the value in the next cell down.
avg = Sum / Count
H = avg '''Column G gets the avg value.
End If
Next Val
End Sub
I know there are some problems with the above code. Im not too familiar with VBA. Also this would print the avg on the same line everytime. Im not sure how to iterate the entire row.
This seems overly complicated. Its a simple problem in theory, but the missing rows and differing number of ID# repetitions makes it more complex.
If this can be done in an Excel function, that would be even better.
Any thoughts or suggestions would be greatly appreciated. thanks.
If you can add another row to the top of your data (put column Headers in it) its quite simple with a formula.
Formula for C2 is
=IF(A2<>A1,AVERAGEIFS(B:B,A:A,A2),"")
copy this down for all data rows.
This applies for Excel 2007 or later. If using Excel 2003 or earlier, use AVERAGEIF instead, adjusting ranges accordingly
If you can't add a header row, change the first formula (cell C1) to
=AVERAGEIFS(B:B,A:A,A1)
In my way ..
Sub calcAvg()
Dim x, y, i, y2, t, Count, Mount As Integer
Dim Seek0 As String
x = 1 '--> means Col A
y = 1 '--> means start - Row 1
y2 = 7 '--> means end - Row 19
For i = y To y2
If i = y Then
Seek0 = Cells(i, x)
t = i
Count = Cells(i, x + 6)
Mount = 1
Else
If Cells(i, x) <> Seek0 Then
Cells(t, x + 7) = Count / Mount
Count = Cells(i, x + 6)
Mount = 1
t = i
Seek0 = Cells(i, x)
Else
Count = Count + Cells(i, x + 6)
Mount = Mount + 1
End If
End If
Next
End Sub
Hope this helps ..
The "B" column has occurence of time in it.Like these
A B
X4T00289 8/4/2011 3:12:07 AM
X4T00289 8/4/2011 3:15:07 AM
X4T00289 8/4/2011 3:18:20 AM
X4T00290 8/4/2011 3:12:37 PM
YCE00194 8/8/2011 5:12:17 AM
YCE00194 8/8/2011 5:14:07 AM
YCE00194 8/10/2011 10:12:06 PM
YCE00194 8/10/2011 10:15:16 AM
Z4W00109 8/12/2011 11:12:22 AM
Z4W00109 8/4/2011 11:58:07 AM
Z4W00109 8/4/2011 12:00:07 PM
I have taken a variant and dumped the range in it like these
var = activesheet.range("A1:B4000").value
QUESTION:
The problem is, I have to identify the consequent rows that has same ID in column A and which occured within 5 minutes and highlight them with color.Take a look at first 2 rows, They occured within 5 minutes and column A value is same for both but the 3rd row occurred after 5 minutes when compared to the first row, So that row should be ignored when highlighting .While coming back to the last 2 rows they also occured within 5 minutes, they should be highlghted with color as they occured within5 minutes. I think you got what i wanted to do. Any questions please comment and I will explain it more cleaner way.
MY APPROACH:
This is what i have tried
, I have used splitting some thing like these
temp = split(text," ")
and then compare temp(0) and temp(1) and temp(2) with consequent rows
temp(0) it has year date and month in it
temp(1) it has Time
temp(2) it has AM or PM
if temp(2) and temp(0) are equal for conesequent rows then this piece of code executes
temp_var=split(temp(1),":") again
again temp_var has temp_var(0)=hours temp_var(1)=minutes temp_var=seconds
Now I have to check hours if hours are equal then
I have to check for minutes like
(minutes - next row minutes) <= 5 then color it
This is what I have done.Im not getting any more better ideas to do it. I guess there might be some other easiest way in do it. may be some inbuilt functions which im not aware of So Let me know is this the only better way to do or any other better approach or algorithm to do it? like faster way to do it?Please help me with this
This is the Code you need, if you need any clarification or change comment here
Sub HighlightDiff()
Dim r As Integer
Dim i As Integer
Dim diff As Integer
Dim y As Integer
Dim m As Integer
Dim d As Integer
Dim h As Integer
r = 4000 ' Total No. of rows
For i = 1 To r
If (Trim(Cells(i, 1).Value) = Trim(Cells(i + 1, 1).Value)) Then
'd = Cells(i, 2).Value - Cells(i + 1, 2).Value
y = Year(Sheet1.Cells(i, 2)) - Year(Sheet1.Cells(i + 1, 2))
m = Month(Sheet1.Cells(i, 2)) - Month(Sheet1.Cells(i + 1, 2))
d = Day(Sheet1.Cells(i, 2)) - Day(Sheet1.Cells(i + 1, 2))
'h = Hour(Sheet1.Cells(i, 2)) - Hour(Sheet1.Cells(i + 1, 2))
If ((y + m + d) = 0) Then
diff = (Hour(Sheet1.Cells(i, 2)) * 60 + Minute(Sheet1.Cells(i, 2))) -
(Hour(Sheet1.Cells(i + 1, 2)) * 60 + Minute(Sheet1.Cells(i + 1, 2)))
If (diff > -5 And diff < 5) Then
Range(Cells(i, 1), Cells(i, 2)).Interior.ColorIndex = 3
End If
End If
End If
Next i
End Sub
here is the algorithm:
for each c in col B
minTime = MIN(col b where ref = current ref)
if c-minTime < 5 min then
change background
end if
next c
Note that you can get dateTime difference simply like this:
if range("onecell")-range("anothercell") < #00:05#
First off, it would be good to ensure that your datetime values in column B are formatted correctly. To do this:
Select all values in column B
Now press CTRL + 1
Select Custom and type in dd/mm/yyyy hh:mm:ss AM/PM
Now you can use the following code to loop through all id's in column A and highlight in red which ones have the same id and are within 5 mins of each other:
Sub WithinFiveMinutes()
Dim rngID As Range, id As Range, timeDiff As Long
Set rngID = Range("A1:A11") //Change for your id list e.g. A1:A4000
For Each id In rngID
If id = id.Offset(1, 0) Then
timeDiff = DateDiff("n", CDate(id.Offset(0, 1)), CDate(id.Offset(1, 1))) //"n" gives time difference in minutes...
If timeDiff >= -5 And timeDiff <= 5 Then
Range(id, id.Offset(0, 1)).Interior.ColorIndex = 3
Range(id.Offset(1, 0), id.Offset(1, 1)).Interior.ColorIndex = 3
End If
End If
Next id
End Sub