Keeping the value of a COUNTIF after removing duplicates (Excel 2007) - excel-2007

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

Related

Inserting Cell Value Performance

My code looks at a table with three different Ids and a qty. It sums all rows where the three ids are the same and pastes it sheet2. The original table is always sorted with the three Id columns sorted in alphabetical order.
Original Table
+--------+------+---------+-----+
| Name | City | Country | Qty |
+--------+------+---------+-----+
| Jack | A | US | 15 |
| Jack | A | US | 16 |
| Kevin | A | US | 12 |
| Kevin | A | US | 11 |
| Jack | B | US | 13 |
| Jack | B | US | 10 |
+--------+------+---------+-----+
Output Table
+--------+------+---------+-----+
| Name | City | Country | Qty |
+--------+------+---------+-----+
| Jack | A | US | 31 |
| Kevin | A | US | 23 |
| Jack | B | US | 23 |
+--------+------+---------+-----+
Code
For i = 2 To totalrow 'totalrow is the total number of rows
name = sheet1.Cells(i, 1)
city = sheet1.Cells(i, 2)
country = sheet1.Cells(i, 3)
qty = 0
Do
qty = qty + sheet1.Cells(i, 4)
i = i + 1
Loop While wsDB.Cells(i, 1) = name And wsDB.Cells(i, 2) = city And wsDB.Cells(i, 3) = country
sheet2.Cells(process_row, 1).Value = name
sheet2.Cells(process_row, 2).Value = city
sheet2.Cells(process_row, 3).Value = country
sheet2.Cells(process_row, 4).Value = qty
process_row = process_row + 1
i = i - 1
Next I
I timed how long the code took to run and it consistently takes 30 seconds.
I then removed the section pasting the updated values into sheet2 and timed it (code below). That consistently took less than 1 second.
For i = 2 To totalrow
bl = wsDB.Cells(i, 1)
cpty = wsDB.Cells(i, 2)
cptyname = wsDB.Cells(i, 3)
cusip = wsDB.Cells(i, 4)
qty = 0
Do
qty = qty + wsDB.Cells(i, 6)
i = i + 1
Loop While wsDB.Cells(i, 1) = bl And wsDB.Cells(i, 2) = cpty And wsDB.Cells(i, 4) = cusip
process_row = process_row + 1
i = i - 1
Next i
It appears that inserting cell values requires the most time. Are there any methods in which I can speed this up?

Excel help for data conversion

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

Issue on create vlookup function and check the condition?

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

VB.NET LINQ Group By Multiple Columns

I have the following LINQ code which has a syntax error and i've no idea how to fix it
Dim query =
From row In mainDatatable.AsEnumerable
'the syntax Error is in the following line
Group row By new { row.Field(Of Double)("cprice") , row.Field(Of Integer)("ccategory")}
Into ProductGroups
'**************************
Dim grpNumber = 1
For Each grp In query
For Each row In grp.ProductGroups
row.SetField("gnum", grpNumber)
Next
grpNumber += 1
Next
End Sub
so what am i doing wrong?
Here is how the table looks like and i want to group by the columns cprice and ccategory
+---------------+---------------+-----------+------+
| Product Name | cprice | ccategory | gnum |
+---------------+---------------+-----------+------+
| Skirt Red | 99 | 1 | |
| Jeans Blue | 49 | 2 | |
| Jeans Black | 49 | 2 | |
| Skirt Blue | 99 | 1 | |
| T-shirt White | 20 | 2 | |
| T-shirt Green | 20 | 2 | |
| Jeans Grey | 49 | 2 | |
+---------------+---------------+-----------+------+
Try this:
new with { Key.Price = row.Field(Of Double)("cprice") ,
Key.Category = row.Field(Of Integer)("ccategory")
Uisng the Key modifier, this creates an anonymous type that implements equality based on equality of its members.

How to initialize a multidimensional array in VB.NET

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?!?