I have data from A1 to BOO66262 and I need to fit everything in seven columns, regardless of the number of rows. I currently have:
| A | B | C | D | E | F | G | H | I | J | K | L | M | N | ... | BOO
1 | x | x | x | x | x | x | x | x | x | x | x | x | x | x | ... | x
... | . | . | . | . | . | . | . | . | . | . | . | . | . | . | ... | .
66262| x | x | x | x | x | x | x | x | x | x | x | x | x | x | ... | x
I need the worksheet to only have seven columns like so:
| A | B | C | D | E | F | G
1 | x | x | x | x | x | x | x
... | x | x | x | x | x | x | x
n | x | x | x | x | x | x | x
Every group has 7 columns but vary in the number of rows. Does anyone know how to do this with VBA?
Here's a screenshot of how my spreadsheet currently looks:
Open the VBE with Alt+F11 and put the following into a module code sheet.
Sub play_tetris()
Dim rws As Long, cls As Long, i As Long
Dim v As Long, vs As Long, vTMP As Variant, vVALs As Variant
Application.ScreenUpdating = False
With Worksheets("Sheet1")
With .Cells(1, 1).CurrentRegion
ReDim vVALs(1 To Application.CountA(.Cells) / 7, 1 To 7)
End With
For cls = 1 To Range("BOO1").Column Step 7
rws = .Cells(Rows.Count, cls).End(xlUp).Row
vTMP = .Cells(1, cls).Resize(rws, 7).Value2
For v = LBound(vTMP, 1) To UBound(vTMP, 1)
vs = vs + 1
For i = 1 To 7
vVALs(vs, i) = vTMP(v, i)
Next i
Next v
Next cls
With .Cells(1, 1).Resize(UBound(vVALs, 1), 7)
.Value = vVALs
.Rows(1).Copy
.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
.Resize(1, Range("BOO1").Column).Offset(0, 7).EntireColumn.Delete
End With
End With
Application.ScreenUpdating = True
End Sub
Adjust the Worksheet .Name property in the fourth line if you are not working on Sheet1. Tap Alt+Q to return to the worksheet then Alt+F8 to open the Macro dialog and Run the macro.
Related
Having the following fields in a table...
+---------+---+---+
| myTime | x | y |
+---------+---+---+
| 13:00 | 0 | 0 |
| 13:05 | 2 | 1 |
| 13:10 | 4 | 2 |
| 13:15 | 1 | 3 |
+---------+---+---+
I need to generate a third one (z) as follows...
+---------+---+---+---+
| myTime | x | y | z |
+---------+---+---+---+
| 13:00 | 0 | 0 | 0 |
| 13:05 | 2 | 1 | 1 |
| 13:10 | 4 | 2 | 3 |
| 13:15 | 1 | 3 | 1 |
+---------+---+---+---+
In the first row z will have a value of 0 and in the next ones, z will be calculated as x-y + (previous row's) z.
I've tried using the row number for each record and LAG to try reading values from previous rows...
WITH rows_sorted AS
(SELECT *, ROW_NUMBER() OVER (ORDER BY myTime) AS row_num
FROM table)
SELECT myTime, x, y
IF(row_num = 1, 0, x - y + LAG(z, 1) OVER (ORDER BY row_num)) AS z
FROM rows_sorted
ORDER BY row_num
...but evidently wouldn't work as in LAG(z, 1), z has not been generated yet.
Any suggestion on how such a thing can be done? I'm using standard SQL in Google BigQuery
Thanks in advance
Since the text above oversimplifies the real calculation, here's a closer approach to what I need to achieve:
+---------+----+----+----+
| myTime | x | y | z |
+---------+----+----+----+
| 13:00 | 15 | 22 | 0 |
| 13:05 | 7 | 21 | 0 |
| 13:10 | 7 | 5 | 2 |
| 13:15 | 9 | 16 | 0 |
| 13:20 | 14 | 5 | 9 |
+---------+----+----+----+
Where z for each row is calculated as follows:
WHEN row_number() = 1 THEN z = 0 (already achieved thanks to the
answer below)
WHEN x+(previous row's)z < y THEN z = 0
WHEN x+(previous row's)z >= y THEN z = x+(previous row's)z - y
Hmmm . . . You can get what you want using:
select t.*,
sum(x - y) over (order by mytime) as z
from t;
The first row has values of 0 for all the columns, so this works for your sample data. If you wanted to explicitly set it to 0, then:
select t.*,
(case when row_number() over order by mytime) = 1
then 0
else sum(x - y) over (order by mytime) - first_value(x - y) over (order by mytime)
end) as z
from t;
This subtracts out the value from the first row from the cumulative sum. However, that seems unnecessary.
Excel Help Needed: I am having the excel sheet with data in below format.
From/to | C1 | C2 | C3 |
---------------------------
R1 | 30 | 31 | 32 |
R2 | 40 | 41 | 42 |
I want to rearrange them in below format using micros/VBA Script or any other feature in excel.
S.no | From| TO |Rate|
-------------------------
1 | R1 | C1 | 30 |
2 | R1 | C2 | 31 |
3 | R1 | C3 | 32 |
4 | R2 | C1 | 40 |
5 | R2 | C2 | 41 |
6 | R2 | C3 | 42 |
Any help for rearranging the excel without manual effort is appreciated
Test bellow.
Sub transData()
Dim vDB, vR()
Dim i As Long, r As Long, j As Integer
Dim n As Long
vDB = Range("a1").CurrentRegion
r = UBound(vDB, 1)
For i = 2 To r
For j = 2 To 4
n = n + 1
ReDim Preserve vR(1 To 4, 1 To n)
vR(1, n) = n
vR(2, n) = vDB(i, 1)
vR(3, n) = vDB(1, j)
vR(4, n) = vDB(i, j)
Next j
Next i
Sheets.Add
Range("a1").Resize(1, 4) = Array("S.no", "From", "TO", "Rate")
Range("a2").Resize(n, 4) = WorksheetFunction.Transpose(vR)
End Sub
I am try to create vlookup function for compare date with in two sheet to find out given date is available in sheet2. If it is not available in sheet 2 means we can create other wise tell message already available for that code
mycode
Sub Button1_Click()
Dim ColNum As Integer
Dim Line As String
Dim LineValues() As Variant
Dim OutputFileNum As Integer
Dim PathName As String
Dim RowNum As Integer
Dim SheetValues() As Variant
PathName = Application.ActiveWorkbook.Path
OutputFileNum = FreeFile
Open PathName & "\Upload Additional PDP.csv" For Output Lock Write As #OutputFileNum
Print #OutputFileNum, "Dist_Code" & "," & "Actual_PDP_Date (dd/MM/yyyy)" & "," & "Reason_Code"
Dim rng1 As Range, rng2 As Range, i As Integer, j As Integer
End Sub
for ex:
1
+--------+--------+---------------+---------+--------+
| A | B | C | D | E |
+--------+--------+---------------+---------+--------+
| Code | Name | Description | Price | Cost | Date
+--------+--------+---------------+---------+--------+
| AC33 | Prod 1 | Prod Desc 1 | 3.99 | 2.00 | 16/7/2014
+--------+--------+---------------+---------+--------+
| AC34 | Prod 2 | Prod Desc 2 | 4.99 | 3.00 | 16/7/2014
+--------+--------+---------------+---------+--------+
| AC35 | Prod 3 | Prod Desc 3 | 5.99 | 4.00 | 16/7/2014
+--------+--------+---------------+---------+--------+
2
+--------+--------+---------------+---------+
| A | B | C | D |
+--------+--------+---------------+---------+
| Code | Name |Updated Price | Cost | Date
+--------+--------+---------------+---------+
| AC33 | Prod 1 | 16.99 | |
+--------+--------+---------------+---------+
| AC37 | Prod 2 | 18.99 | |
+--------+--------+---------------+---------+
| AC38 | Prod 3 | 21.99 | |
+--------+--------+---------------+---------+
Use the IsError function to test the result of the VLOOKUP, here's something to get you started:
If IsError(Application.VLookup(Range("A1"), Range("C:C"), 1, False)) Then
Debug.Print "Not found"
Else
Debug.Print "Found"
End If
I am trying to initialize a multidimensional array. Here is my syntax; this does not create errors but it does not store all values either. Although it correctly prints out all records in this snippet,
dFirstWeek = CDate(FirstWeek)
dFirstWeek = DateAdd(DateInterval.WeekOfYear, -1, dFirstWeek)
Dim dFirstDay As Date
Dim arrWeekYear(5000, 1) As Date
Dim i As Integer = 0
Dim j As Integer = 0
dFirstDay = dFirstDay.AddDays(1)
While dFirstWeek <= dLastWeek
dFirstDay = dFirstWeek
dFirstWeek = dFirstWeek.AddDays(7)
While dFirstDay < dFirstWeek
arrWeekYear(i, j) = (dFirstWeek)
arrWeekYear(i, j + 1) = (dFirstDay)
Response.Write(arrWeekYear(i, j).ToString("d"))
Response.Write(" ;")
Response.Write(arrWeekYear(i, j + 1).ToString("d"))
Response.Write("<br>")
dFirstDay = dFirstDay.AddDays(1)
j = 0
End While
i = i + 1
End While
later in this code, I try to reprint this array as follows:
i = 0
j = 0
Dim k As Integer = 0
'Response.Write(arrWeekYear.GetLength(0))
While k < arrWeekYear.GetLength(0) - 2
Response.Write(arrWeekYear(i, j).ToString("d"))
Response.Write(" ;")
Response.Write(arrWeekYear(i, j + 1).ToString("d"))
Response.Write("<br>")
j = 0
i = i + 1
k = k + 1
End While
but this time, only one "j" record appears per "i" record. Why is this? And then after these few records, many dates resembling null dates appear: "1/1/0001 "
So why do all records appear in upper section, but not from lower? Did I insert values wrongly into this array? And it does not have to have fixed number of rows, just a fixed number of columns.
Dim arrWeekYear(5000, 1) As Date
That’s a multi-dimensional array all right, but the second dimension only has a size of 2! And you access it via j, which is always 0 in your code. That makes no sense. Is that really what you want? I suggest you use a data structure inside your array instead of a multi-dimensional array.
In fact, you almost never want to use a multi-dimensional array. At all. Complex objects are almost always more appropriate. The only real exception is when you actually want to store a mathematical matrix.
Increment i inside the inner loop, rather than inside the outer loop.
And even simpler code (requires visual studio 2010):
Dim baseDate As Datetime = Convert.ToDatetime(FirstWeek).AddDays(-7)
For Each item In Enumerable.Range(0, (dLastWeek - baseDate).TotalDays / 7) _
.Select(Function(i) New DateTime() _
{baseDate.AddDays(i*7), baseDate.AddDays(i*7 + 7) })
Response.Write(string.Format("{0:d} ;{1:d}<br/>", item(0), item(1)))
Next item
And since Response.Write() is frowned upon in asp.net, you can take this a step further and assign the Enumerable.Range() call as the datasource for an asp:repeater control, if you're using webforms rather than mvc.
In the first piece you fill the array writing 7 times a value in the same array line.
In a test (from 01/01/2011 to 03/03/2011) the first 21 assignments are:
i | j | value | j+1 | value
0 | 0 | 01/01/2011 | 1 | 25/12/2010
0 | 0 | 01/01/2011 | 1 | 26/12/2010
0 | 0 | 01/01/2011 | 1 | 27/12/2010
0 | 0 | 01/01/2011 | 1 | 28/12/2010
0 | 0 | 01/01/2011 | 1 | 29/12/2010
0 | 0 | 01/01/2011 | 1 | 30/12/2010
0 | 0 | 01/01/2011 | 1 | 31/12/2010 final value in array (0,0) and (0,1)
1 | 0 | 08/01/2011 | 1 | 01/01/2011
1 | 0 | 08/01/2011 | 1 | 02/01/2011
1 | 0 | 08/01/2011 | 1 | 03/01/2011
1 | 0 | 08/01/2011 | 1 | 04/01/2011
1 | 0 | 08/01/2011 | 1 | 05/01/2011
1 | 0 | 08/01/2011 | 1 | 06/01/2011
1 | 0 | 08/01/2011 | 1 | 07/01/2011 final value in array (1,0) and 1,1)
2 | 0 | 15/01/2011 | 1 | 08/01/2011
2 | 0 | 15/01/2011 | 1 | 09/01/2011
2 | 0 | 15/01/2011 | 1 | 10/01/2011
2 | 0 | 15/01/2011 | 1 | 11/01/2011
2 | 0 | 15/01/2011 | 1 | 12/01/2011
2 | 0 | 15/01/2011 | 1 | 13/01/2011
2 | 0 | 15/01/2011 | 1 | 14/01/2011 final value in array (2,0) and (2,1)
etc.
In the 2nd part you get the values written :
i | j | value | j+1 | value
0 | 0 | 01/01/2011 | 1 | 31/12/2010
1 | 0 | 08/01/2011 | 1 | 07/01/2011
2 | 0 | 15/01/2011 | 1 | 14/01/2011
3 | 0 | 22/01/2011 | 1 | 21/01/2011
4 | 0 | 29/01/2011 | 1 | 28/01/2011
5 | 0 | 05/02/2011 | 1 | 04/02/2011
6 | 0 | 12/02/2011 | 1 | 11/02/2011
7 | 0 | 19/02/2011 | 1 | 18/02/2011
8 | 0 | 26/02/2011 | 1 | 25/02/2011
9 | 0 | 05/03/2011 | 1 | 04/03/2011
10 | 0 | 01/01/0001 | 1 | 01/01/0001
and this is the value in the rest of the array.
I think you forgot to increment some value in part 1?!?
I have a spreadsheet with multiple duplicate rows. I need this data sorted in order of their frequency, so I setup a COUNTIF and sorted them. Now I would like to remove the duplicate rows, but keep the COUNTIF at the same value and have Excel add to it if other duplicates are added to the spreadsheet in the future.
How can I go about doing this?
EDIT:
This may make it a little more complex, but below is an example of the data as it is now (the last number denotes the number of occurances; with my COUNTIF):
123 | Yes | 2,901 | 4,243 | 5555 | John | 4
123 | Yes | 2,919 | 4,528 | 5555 | John | 4
123 | Yes | 2,901 | 4,243 | 5555 | John | 4
123 | Yes | 4,243 | 4,128 | 5555 | John | 4
111 | 80 | 2,919 | 4,452 | 2222 | Joe | 2
111 | 80 | 11,00 | 2,901 | 2222 | Joe | 2
And this is how I need it to be:
123 | Yes | 2,901 | 4,243 | 5555 | John | 4
111 | 80 | 2,919 | 4,452 | 2222 | Joe | 2
Notice that despite some of the values not being an exact match the first cells (column A) are the same.
Hope that makes it a little more clear.
In case anyone is interested, below is the solution to my problem.
Sub Count()
Dim sID As String
Dim sOldID As String
Dim lLastRow As Long
Dim lrow As Long
Dim lcount As Long
lLastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
lrow = 2
sID = ActiveSheet.Cells(lrow, 1).Value
sOldID = ActiveSheet.Cells(1, 1).Value
lcount = 1
Do While Len(sID) <> 0
If sID <> sOldID Then
ActiveSheet.Cells(lrow - 1, 19).Value = lcount
sOldID = sID
lcount = 1
lrow = lrow + 1
Else
lcount = lcount + 1
ActiveSheet.Rows(lrow).Select
Selection.Delete Shift:=xlUp
End If
sID = ActiveSheet.Cells(lrow, 1).Value
Loop
ActiveSheet.Cells(lrow - 1, 19).Value = lcount
End Sub