How to transform Excel Data - excel

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

Related

Subtract and paste answer in subsequent rows until the value changes again

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

Macro to Calendarize Data

Problem:
I am writing a macro to do some data input for me. These data reports all have the same format (date in column 1, value in column 2), except the order of the months of data change from client to client. Currently I have written the macro to grab the data from another sheet and bring it into the current sheet. But now I need to write something to take the data and get it into the correct format.
Example: This client is organized from Apr-Mar (again, it could be any 12 month combination) and I need to get it into Jan-Dec, regardless of year.
Before:
Apr-14 37,645
May-14 47,000
Jun-14 11,600
Jul-14 33,503
Aug-14 38,550
Sep-14 36,063
Oct-14 39,246
Nov-14 30,315
Dec-14 28,403
Jan-15 25,799
Feb-15 24,302
Mar-15 27,873
After:
Jan-15 25,799
Feb-15 24,302
Mar-15 27,873
Apr-14 37,645
May-14 47,000
Jun-14 11,600
Jul-14 33,503
Aug-14 38,550
Sep-14 36,063
Oct-14 39,246
Nov-14 30,315
Dec-14 28,403
Attempt at a Solution:
I am hesitant to post it as it's incomplete and would be hard to follow. All it does is parse the first date cell to get the first 3 letters corresponding to a month, then check against 12 if/elseif statements. There must be a better way to write it, I just can't think of it.
Any and all help is appreciated. I'm sure a shove in the right direction would help!
I ended up just creating a loop that looks for "Jan" and gets all the data from there.
'Loop to dynamically calendarize data
''Loop returns 2 arrays, length 12, index 0-11, "electic" and "heating" in Jan to Dec format
complete = False
For i = 9 To 20
If Left(target.Sheets("Sheet1").Cells(i, 1).Value, 3) = "Jan" Then
For j = 0 To (20 - i)
carryOver = i + j
electric(j) = target.Sheets("Sheet1").Cells(carryOver, 2).Value
heating(j) = target.Sheets("Sheet1").Cells(carryOver, 5).Value
Next j
complete = True
ElseIf complete = True Then
For k = j To 11
electric(k) = target.Sheets("Sheet1").Cells(9 + (k - j), 2).Value
heating(k) = target.Sheets("Sheet1").Cells(9 + (k - j), 5).Value
Next k
GoTo end_of_for
End If
Next i
end_of_for:

Sum all rows in excel with the same value in a certain column

So basically I will have a changing list of names entered like so
Deborah 9 30
Steven 4 22
Michelle 9 26
Michelle 8 30
Alice 10 28
John 3 21
David 7 23
David 9 26
David 7 24
Lucy 6 24
and my goal is to write a macros so that the names appear like this
Deborah 9 30
Steven 4 22
Michelle 17 56
Alice 10 28
John 3 21
David 23 73
Lucy 6 24
so all the rows with the same value for column 1 will be a sum of the values in the other column and consolidated to one row. The names are going to be changing, so I cant hardcode in IF something = "Michelle" it has to just be IF these rows = these other rows. I am trying to automate a tedious task at work, thanks for any suggestions!
If the duplicated names are in consecutive rows, then try this short macro:
Sub DeDup()
Dim N As Long, i As Long
N = Cells(Rows.Count, "A").End(xlUp).Row
For i = N To 2 Step -1
If Cells(i, 1) = Cells(i - 1, 1) Then
Cells(i - 1, 2) = Cells(i - 1, 2) + Cells(i, 2)
Cells(i - 1, 3) = Cells(i - 1, 3) + Cells(i, 3)
Range(Cells(i, 1), Cells(i, 3)).Delete Shift:=xlUp
End If
Next i
End Sub
You can create a distinct sorted list of names using an array formula with INDEX, MATCH, MAX and COUNTIF as described here:
http://www.get-digital-help.com/2009/04/14/create-a-unique-alphabetically-sorted-list-extracted-from-a-column/
Then you can just use a simple SUMIF function for each name in the result.
Just use a sumif formula. you can manipulate it to your needs. It will sum what you want in a given row. Or use an array if you would like.

Auto calculate average over varying number values row by row

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 ..

Updating column values on specific Row using VBA

How to update value from xt to xtt in 6th column, first row.
1 2 3 4 5 6
x xx xy xz x1 xt
y yx tt cc z3 xcc
Based on above data, I am getting range from worksheet. After getting the Row object, how do I update the Cell value in particular column?
As asked, you can update a specific column using the method:
'Sheet.Cells(row, column) = value
' i.e.
ActiveSheet.Cells(1, 6) = "xtt"
If you only want to perform the update if it has a value of "xt", then obviously you'd need to check the contents before performing the update... For example:
If (ActiveSheet.Cells(1, 6) = "xt") Then
ActiveSheet.Cells(1, 6) = "xtt"
End If

Resources