Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 33
Default Splitting & Listing Unique values from cells

Hi, I have an array of data as per below in 'OldWorksheet':

Supply Category Supplier
Product 1 Supplier 1;Supplier 3
Product 2 Supplier 2
Product 3 Supplier 1;Supplier 3;Supplier 6
Product 2 Supplier 5
Product 2 Supplier 4;Supplier 5
Product 2 Supplier 1;Supplier 2;Supplier 3
Product 4 Supplier 2
Product 4 Supplier 2;Supplier 1
Product 4 Supplier 5;Supplier 1
Product 5 Supplier 3
Product 5 Supplier 4;Supplier 5
Product 6 Supplier 4
Product 1 Supplier 3

What I need to do is create a list of Unique Suppliers (Column A,
'Newworksheet'), with the products they supply (In Column B, 'Newworksheet')
- if multiple products, they can either be all in the same cell and
separated, or in subsequent columns (C, D, E etc.)

Logically I imagine it involves:
1. Using text-to-columns to initially split the supplier names out into
seperate cells
2. Identifying the unique records in the array
3. Copying this list to 'NewWorksheet'!Column A
4. Sequentially looking up each product by supplier from 'OldWorksheet' and
placing them in 'NewWorksheet'!Column B, C, D etc.

Any hints, I imagine it needs some logic applied as well as Excel & VBA.

Thanks


  #2   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 9,101
Default Splitting & Listing Unique values from cells

See if this works. the program assume Newworksheet exists. If not make a
blank Newworksheet.

subroutine GetSuppliers reads Oldworksheet
Subroutine AddSupplier adds supplier and product if they don't exist.


Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)
'strip off any leading blanks
For i = 1 To Len(SupplierCell)
If StrComp(Mid(SupplierCell, i, 1), " ") < 0 Then Exit For
Next i
SupplierCell = Mid(SupplierCell, i)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Hi, I have an array of data as per below in 'OldWorksheet':

Supply Category Supplier
Product 1 Supplier 1;Supplier 3
Product 2 Supplier 2
Product 3 Supplier 1;Supplier 3;Supplier 6
Product 2 Supplier 5
Product 2 Supplier 4;Supplier 5
Product 2 Supplier 1;Supplier 2;Supplier 3
Product 4 Supplier 2
Product 4 Supplier 2;Supplier 1
Product 4 Supplier 5;Supplier 1
Product 5 Supplier 3
Product 5 Supplier 4;Supplier 5
Product 6 Supplier 4
Product 1 Supplier 3

What I need to do is create a list of Unique Suppliers (Column A,
'Newworksheet'), with the products they supply (In Column B, 'Newworksheet')
- if multiple products, they can either be all in the same cell and
separated, or in subsequent columns (C, D, E etc.)

Logically I imagine it involves:
1. Using text-to-columns to initially split the supplier names out into
seperate cells
2. Identifying the unique records in the array
3. Copying this list to 'NewWorksheet'!Column A
4. Sequentially looking up each product by supplier from 'OldWorksheet' and
placing them in 'NewWorksheet'!Column B, C, D etc.

Any hints, I imagine it needs some logic applied as well as Excel & VBA.

Thanks


  #3   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 33
Default Splitting & Listing Unique values from cells

Thanks Joel - you've given me heaps of clues, but it wasn't quite on the
money -

Effectively, once it has done what you gave me, it also needs to be able to
combine duplicate suppliers and products. This is where the problem lies, and
increasingly I think that this is simply not possible!

Therefore, using the original example, the finish in NewWorksheet should
look something like;

Supply Category Supplier
Supplier 1 Product 1; Product 3; Product 2; Product 4
Supplier 2 Product 2; Product 4
Supplier 3 Product 1; Product 3; Product 2; Product 5
Supplier 4 Product 2; Product 5; Product 6
Supplier 5 Product 2; Product 4; Product 5
Supplier 6 Product 3

I think the trick is more in how to filter unique entries from an array
(Suppliers), copy and paste that list into the new worksheet, then
systematically lookup that value in the array of products and paste them in
the columns across from the Supplier.

But welcome to any suggestions, and your code is certainly an improvement
from what I had...

the usual trick of recording the acion and cleaning up the code doesn't
work, since the array can be any size...


"Joel" wrote:

See if this works. the program assume Newworksheet exists. If not make a
blank Newworksheet.

subroutine GetSuppliers reads Oldworksheet
Subroutine AddSupplier adds supplier and product if they don't exist.


Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)
'strip off any leading blanks
For i = 1 To Len(SupplierCell)
If StrComp(Mid(SupplierCell, i, 1), " ") < 0 Then Exit For
Next i
SupplierCell = Mid(SupplierCell, i)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Hi, I have an array of data as per below in 'OldWorksheet':

Supply Category Supplier
Product 1 Supplier 1;Supplier 3
Product 2 Supplier 2
Product 3 Supplier 1;Supplier 3;Supplier 6
Product 2 Supplier 5
Product 2 Supplier 4;Supplier 5
Product 2 Supplier 1;Supplier 2;Supplier 3
Product 4 Supplier 2
Product 4 Supplier 2;Supplier 1
Product 4 Supplier 5;Supplier 1
Product 5 Supplier 3
Product 5 Supplier 4;Supplier 5
Product 6 Supplier 4
Product 1 Supplier 3

What I need to do is create a list of Unique Suppliers (Column A,
'Newworksheet'), with the products they supply (In Column B, 'Newworksheet')
- if multiple products, they can either be all in the same cell and
separated, or in subsequent columns (C, D, E etc.)

Logically I imagine it involves:
1. Using text-to-columns to initially split the supplier names out into
seperate cells
2. Identifying the unique records in the array
3. Copying this list to 'NewWorksheet'!Column A
4. Sequentially looking up each product by supplier from 'OldWorksheet' and
placing them in 'NewWorksheet'!Column B, C, D etc.

Any hints, I imagine it needs some logic applied as well as Excel & VBA.

Thanks


  #4   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 9,101
Default Splitting & Listing Unique values from cells

I ran your data and below are the results I got. I believe it is doing the
filtering you have asked for.


Product 1 Supplier 1 Supplier 3
Product 2 Supplier 2 Supplier 5 Supplier 4 Supplier 1 Supplier 3
Product 3 Supplier 1 Supplier 3 Supplier 6
Product 4 Supplier 2 Supplier 1 Supplier 5
Product 5 Supplier 3 Supplier 4 Supplier 5
Product 6 Supplier 4


"D Zandveld" wrote:

Thanks Joel - you've given me heaps of clues, but it wasn't quite on the
money -

Effectively, once it has done what you gave me, it also needs to be able to
combine duplicate suppliers and products. This is where the problem lies, and
increasingly I think that this is simply not possible!

Therefore, using the original example, the finish in NewWorksheet should
look something like;

Supply Category Supplier
Supplier 1 Product 1; Product 3; Product 2; Product 4
Supplier 2 Product 2; Product 4
Supplier 3 Product 1; Product 3; Product 2; Product 5
Supplier 4 Product 2; Product 5; Product 6
Supplier 5 Product 2; Product 4; Product 5
Supplier 6 Product 3

I think the trick is more in how to filter unique entries from an array
(Suppliers), copy and paste that list into the new worksheet, then
systematically lookup that value in the array of products and paste them in
the columns across from the Supplier.

But welcome to any suggestions, and your code is certainly an improvement
from what I had...

the usual trick of recording the acion and cleaning up the code doesn't
work, since the array can be any size...


"Joel" wrote:

See if this works. the program assume Newworksheet exists. If not make a
blank Newworksheet.

subroutine GetSuppliers reads Oldworksheet
Subroutine AddSupplier adds supplier and product if they don't exist.


Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)
'strip off any leading blanks
For i = 1 To Len(SupplierCell)
If StrComp(Mid(SupplierCell, i, 1), " ") < 0 Then Exit For
Next i
SupplierCell = Mid(SupplierCell, i)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Hi, I have an array of data as per below in 'OldWorksheet':

Supply Category Supplier
Product 1 Supplier 1;Supplier 3
Product 2 Supplier 2
Product 3 Supplier 1;Supplier 3;Supplier 6
Product 2 Supplier 5
Product 2 Supplier 4;Supplier 5
Product 2 Supplier 1;Supplier 2;Supplier 3
Product 4 Supplier 2
Product 4 Supplier 2;Supplier 1
Product 4 Supplier 5;Supplier 1
Product 5 Supplier 3
Product 5 Supplier 4;Supplier 5
Product 6 Supplier 4
Product 1 Supplier 3

What I need to do is create a list of Unique Suppliers (Column A,
'Newworksheet'), with the products they supply (In Column B, 'Newworksheet')
- if multiple products, they can either be all in the same cell and
separated, or in subsequent columns (C, D, E etc.)

Logically I imagine it involves:
1. Using text-to-columns to initially split the supplier names out into
seperate cells
2. Identifying the unique records in the array
3. Copying this list to 'NewWorksheet'!Column A
4. Sequentially looking up each product by supplier from 'OldWorksheet' and
placing them in 'NewWorksheet'!Column B, C, D etc.

Any hints, I imagine it needs some logic applied as well as Excel & VBA.

Thanks


  #5   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 9,101
Default Splitting & Listing Unique values from cells

Tis morning when I was working on the program I found spaces in the data you
posted a manually removed these spaces. I realized I could improve the
program. there are 3 reasons the products and suppliers weren't combining

I always try to get a program to run under ANY condition. Error checking is
always an important part of a program.

1) Extra Spaces - I emoved the spaces and bgining and End of Products and
Suppliers.
2) The case (Upper Case or Lower Case) weren't the same between entries. I
converted all Products and Suppliers so 1st letter of every word is capital
and rest of words are lower case.
3) Spelling Errors in Products and suppliers. I can't fix spelling. If
items don't combine, carefully check the Spelling for typos in data. I often
don't find the typo errors until I run a program on teh data. Often I have
to fix the typos and re-run the program.

I'm filtering the data with the strcomp() function. Only adding items that
aren't previously in the newworksheet.

Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
'strip off leading and trailing blanks
For i = 1 To Len(Product)
If StrComp(Mid(Product, i, 1), " ") < 0 Then Exit For
Next i
Product = Mid(Product, i)

For i = Len(Product) To 1 Step -1
If StrComp(Mid(Product, i, 1), " ") < 0 Then Exit For
Next i
Product = Left(Product, i)

SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

'strip off leading and trailing blanks
For i = 1 To Len(Supplier)
If StrComp(Mid(Supplier, i, 1), " ") < 0 Then Exit For
Next i
Supplier = Mid(Supplier, i)

For i = Len(Supplier) To 1 Step -1
If StrComp(Mid(Supplier, i, 1), " ") < 0 Then Exit For
Next i
Supplier = Left(Supplier, i)

'Convert String to first letter Capital
Product = StrConv(Product, vbLowerCase)
Product = StrConv(Product, vbProperCase)

Supplier = StrConv(Supplier, vbLowerCase)
Supplier = StrConv(Supplier, vbProperCase)

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Thanks Joel - you've given me heaps of clues, but it wasn't quite on the
money -

Effectively, once it has done what you gave me, it also needs to be able to
combine duplicate suppliers and products. This is where the problem lies, and
increasingly I think that this is simply not possible!

Therefore, using the original example, the finish in NewWorksheet should
look something like;

Supply Category Supplier
Supplier 1 Product 1; Product 3; Product 2; Product 4
Supplier 2 Product 2; Product 4
Supplier 3 Product 1; Product 3; Product 2; Product 5
Supplier 4 Product 2; Product 5; Product 6
Supplier 5 Product 2; Product 4; Product 5
Supplier 6 Product 3

I think the trick is more in how to filter unique entries from an array
(Suppliers), copy and paste that list into the new worksheet, then
systematically lookup that value in the array of products and paste them in
the columns across from the Supplier.

But welcome to any suggestions, and your code is certainly an improvement
from what I had...

the usual trick of recording the acion and cleaning up the code doesn't
work, since the array can be any size...


"Joel" wrote:

See if this works. the program assume Newworksheet exists. If not make a
blank Newworksheet.

subroutine GetSuppliers reads Oldworksheet
Subroutine AddSupplier adds supplier and product if they don't exist.


Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)
'strip off any leading blanks
For i = 1 To Len(SupplierCell)
If StrComp(Mid(SupplierCell, i, 1), " ") < 0 Then Exit For
Next i
SupplierCell = Mid(SupplierCell, i)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Hi, I have an array of data as per below in 'OldWorksheet':

Supply Category Supplier
Product 1 Supplier 1;Supplier 3
Product 2 Supplier 2
Product 3 Supplier 1;Supplier 3;Supplier 6
Product 2 Supplier 5
Product 2 Supplier 4;Supplier 5
Product 2 Supplier 1;Supplier 2;Supplier 3
Product 4 Supplier 2
Product 4 Supplier 2;Supplier 1
Product 4 Supplier 5;Supplier 1
Product 5 Supplier 3
Product 5 Supplier 4;Supplier 5
Product 6 Supplier 4
Product 1 Supplier 3

What I need to do is create a list of Unique Suppliers (Column A,
'Newworksheet'), with the products they supply (In Column B, 'Newworksheet')
- if multiple products, they can either be all in the same cell and
separated, or in subsequent columns (C, D, E etc.)

Logically I imagine it involves:
1. Using text-to-columns to initially split the supplier names out into
seperate cells
2. Identifying the unique records in the array
3. Copying this list to 'NewWorksheet'!Column A
4. Sequentially looking up each product by supplier from 'OldWorksheet' and
placing them in 'NewWorksheet'!Column B, C, D etc.

Any hints, I imagine it needs some logic applied as well as Excel & VBA.

Thanks




  #6   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 33
Default Splitting & Listing Unique values from cells

Hi Joel

Will try your revised code, and see how it goes.

Just one other 'twist', what if the Products are in Column C and Suppliers
in Column V? I worked out the how to move the reverence for the suppliers by
changing columnoffset:=1 to columnoffset:=20, but how do I get it to read
Column C as the first ?

FYI, the spelling is not a great concern - the suppliers are all Chinese, so
spelling is not a priority!

Appreciate your assistance, this is the final hurdle before it is finished!

Thanks

"Joel" wrote:

Tis morning when I was working on the program I found spaces in the data you
posted a manually removed these spaces. I realized I could improve the
program. there are 3 reasons the products and suppliers weren't combining

I always try to get a program to run under ANY condition. Error checking is
always an important part of a program.

1) Extra Spaces - I emoved the spaces and bgining and End of Products and
Suppliers.
2) The case (Upper Case or Lower Case) weren't the same between entries. I
converted all Products and Suppliers so 1st letter of every word is capital
and rest of words are lower case.
3) Spelling Errors in Products and suppliers. I can't fix spelling. If
items don't combine, carefully check the Spelling for typos in data. I often
don't find the typo errors until I run a program on teh data. Often I have
to fix the typos and re-run the program.

I'm filtering the data with the strcomp() function. Only adding items that
aren't previously in the newworksheet.

Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
'strip off leading and trailing blanks
For i = 1 To Len(Product)
If StrComp(Mid(Product, i, 1), " ") < 0 Then Exit For
Next i
Product = Mid(Product, i)

For i = Len(Product) To 1 Step -1
If StrComp(Mid(Product, i, 1), " ") < 0 Then Exit For
Next i
Product = Left(Product, i)

SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

'strip off leading and trailing blanks
For i = 1 To Len(Supplier)
If StrComp(Mid(Supplier, i, 1), " ") < 0 Then Exit For
Next i
Supplier = Mid(Supplier, i)

For i = Len(Supplier) To 1 Step -1
If StrComp(Mid(Supplier, i, 1), " ") < 0 Then Exit For
Next i
Supplier = Left(Supplier, i)

'Convert String to first letter Capital
Product = StrConv(Product, vbLowerCase)
Product = StrConv(Product, vbProperCase)

Supplier = StrConv(Supplier, vbLowerCase)
Supplier = StrConv(Supplier, vbProperCase)

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Thanks Joel - you've given me heaps of clues, but it wasn't quite on the
money -

Effectively, once it has done what you gave me, it also needs to be able to
combine duplicate suppliers and products. This is where the problem lies, and
increasingly I think that this is simply not possible!

Therefore, using the original example, the finish in NewWorksheet should
look something like;

Supply Category Supplier
Supplier 1 Product 1; Product 3; Product 2; Product 4
Supplier 2 Product 2; Product 4
Supplier 3 Product 1; Product 3; Product 2; Product 5
Supplier 4 Product 2; Product 5; Product 6
Supplier 5 Product 2; Product 4; Product 5
Supplier 6 Product 3

I think the trick is more in how to filter unique entries from an array
(Suppliers), copy and paste that list into the new worksheet, then
systematically lookup that value in the array of products and paste them in
the columns across from the Supplier.

But welcome to any suggestions, and your code is certainly an improvement
from what I had...

the usual trick of recording the acion and cleaning up the code doesn't
work, since the array can be any size...


"Joel" wrote:

See if this works. the program assume Newworksheet exists. If not make a
blank Newworksheet.

subroutine GetSuppliers reads Oldworksheet
Subroutine AddSupplier adds supplier and product if they don't exist.


Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)
'strip off any leading blanks
For i = 1 To Len(SupplierCell)
If StrComp(Mid(SupplierCell, i, 1), " ") < 0 Then Exit For
Next i
SupplierCell = Mid(SupplierCell, i)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Hi, I have an array of data as per below in 'OldWorksheet':

Supply Category Supplier
Product 1 Supplier 1;Supplier 3
Product 2 Supplier 2
Product 3 Supplier 1;Supplier 3;Supplier 6
Product 2 Supplier 5
Product 2 Supplier 4;Supplier 5
Product 2 Supplier 1;Supplier 2;Supplier 3

  #7   Report Post  
Posted to microsoft.public.excel.programming
external usenet poster
 
Posts: 9,101
Default Splitting & Listing Unique values from cells

For suppliers I like this form of the equation better. I thought it was
clearer when it was the adjacent colunm to use an offset. When you are going
all the way out to column V I think its clear to just use the
cells(row,column) format. Not sure why you got an offset of 20. The
offset was from the range where the Product column. If you were going from
column A to column V it would be 21. If you were going from column C to V it
would be 19. It was originally Column A and now column C. You chose an
Offset from column B (the old supplier column) which is wrong according to
the way the code is designed. Using the cells(row,column) format of the
equation would prevent this type error.

from:
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=21)
to:
SupplierCell = Sheets(OldWs).cells(OldWsCell.row,22)


for Products change
from:
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

to:
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 3), Cells(LastRowOldWs, 3))








"D Zandveld" wrote:

Hi Joel

Will try your revised code, and see how it goes.

Just one other 'twist', what if the Products are in Column C and Suppliers
in Column V? I worked out the how to move the reverence for the suppliers by
changing columnoffset:=1 to columnoffset:=20, but how do I get it to read
Column C as the first ?

FYI, the spelling is not a great concern - the suppliers are all Chinese, so
spelling is not a priority!

Appreciate your assistance, this is the final hurdle before it is finished!

Thanks

"Joel" wrote:

Tis morning when I was working on the program I found spaces in the data you
posted a manually removed these spaces. I realized I could improve the
program. there are 3 reasons the products and suppliers weren't combining

I always try to get a program to run under ANY condition. Error checking is
always an important part of a program.

1) Extra Spaces - I emoved the spaces and bgining and End of Products and
Suppliers.
2) The case (Upper Case or Lower Case) weren't the same between entries. I
converted all Products and Suppliers so 1st letter of every word is capital
and rest of words are lower case.
3) Spelling Errors in Products and suppliers. I can't fix spelling. If
items don't combine, carefully check the Spelling for typos in data. I often
don't find the typo errors until I run a program on teh data. Often I have
to fix the typos and re-run the program.

I'm filtering the data with the strcomp() function. Only adding items that
aren't previously in the newworksheet.

Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
'strip off leading and trailing blanks
For i = 1 To Len(Product)
If StrComp(Mid(Product, i, 1), " ") < 0 Then Exit For
Next i
Product = Mid(Product, i)

For i = Len(Product) To 1 Step -1
If StrComp(Mid(Product, i, 1), " ") < 0 Then Exit For
Next i
Product = Left(Product, i)

SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

'strip off leading and trailing blanks
For i = 1 To Len(Supplier)
If StrComp(Mid(Supplier, i, 1), " ") < 0 Then Exit For
Next i
Supplier = Mid(Supplier, i)

For i = Len(Supplier) To 1 Step -1
If StrComp(Mid(Supplier, i, 1), " ") < 0 Then Exit For
Next i
Supplier = Left(Supplier, i)

'Convert String to first letter Capital
Product = StrConv(Product, vbLowerCase)
Product = StrConv(Product, vbProperCase)

Supplier = StrConv(Supplier, vbLowerCase)
Supplier = StrConv(Supplier, vbProperCase)

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Sheets(NewWs).Cells(Productrow, 1) = Product
Sheets(NewWs).Cells(Productrow, 2) = Supplier

End If
End Sub


"D Zandveld" wrote:

Thanks Joel - you've given me heaps of clues, but it wasn't quite on the
money -

Effectively, once it has done what you gave me, it also needs to be able to
combine duplicate suppliers and products. This is where the problem lies, and
increasingly I think that this is simply not possible!

Therefore, using the original example, the finish in NewWorksheet should
look something like;

Supply Category Supplier
Supplier 1 Product 1; Product 3; Product 2; Product 4
Supplier 2 Product 2; Product 4
Supplier 3 Product 1; Product 3; Product 2; Product 5
Supplier 4 Product 2; Product 5; Product 6
Supplier 5 Product 2; Product 4; Product 5
Supplier 6 Product 3

I think the trick is more in how to filter unique entries from an array
(Suppliers), copy and paste that list into the new worksheet, then
systematically lookup that value in the array of products and paste them in
the columns across from the Supplier.

But welcome to any suggestions, and your code is certainly an improvement
from what I had...

the usual trick of recording the acion and cleaning up the code doesn't
work, since the array can be any size...


"Joel" wrote:

See if this works. the program assume Newworksheet exists. If not make a
blank Newworksheet.

subroutine GetSuppliers reads Oldworksheet
Subroutine AddSupplier adds supplier and product if they don't exist.


Sub GetSuppliers()

Const OldWs = "OldWorksheet"
Dim Product As String
Dim Supplier As String

LastRowOldWs = Sheets(OldWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(OldWs).Activate
Set OldWsRange = Sheets(OldWs). _
Range(Cells(2, 1), Cells(LastRowOldWs, 1))

For Each OldWsCell In OldWsRange

'Get Product and supplier
Product = OldWsCell.Value
SupplierCell = OldWsCell.Offset(rowoffset:=0, columnoffset:=1)
'strip off any leading blanks
For i = 1 To Len(SupplierCell)
If StrComp(Mid(SupplierCell, i, 1), " ") < 0 Then Exit For
Next i
SupplierCell = Mid(SupplierCell, i)

'get each supplier
Do While Len(SupplierCell) < 0

If InStr(SupplierCell, ";") Then

Supplier = Left(SupplierCell, InStr(SupplierCell, ";") - 1)
SupplierCell = Mid(SupplierCell, _
InStr(SupplierCell, ";") + 1)
Else
Supplier = SupplierCell
SupplierCell = ""
End If

Call AddSupplier(Product, Supplier)
Loop

Next OldWsCell


End Sub

Sub AddSupplier(Product As String, Supplier As String)

Const NewWs = "NewWorksheet"

LastRowNewWs = Sheets(NewWs).Cells(Rows.Count, 1).End(xlUp).Row
Sheets(NewWs).Activate
Set NewWsRange = Sheets(NewWs). _
Range(Cells(1, 1), Cells(LastRowNewWs, 1))

FoundProduct = False
For Each NewWsCell In NewWsRange

If StrComp(NewWsCell, Product) = 0 Then

FoundProduct = True
'found product now check supplier
LastColNewWs = Sheets(NewWs). _
Cells(NewWsCell.Row, Columns.Count).End(xlToLeft).Column
Set SupplietRange = Sheets(NewWs). _
Range(Cells(NewWsCell.Row, 2), _
Cells(NewWsCell.Row, LastColNewWs))

FoundSupplier = False
For Each SupplierCell In SupplietRange

If StrComp(Supplier, SupplierCell) = 0 Then

FoundSupplier = True
Exit For
End If


Next SupplierCell

'this is new supplier so add supplier
If FoundSupplier = False Then

Sheets(NewWs).Cells(NewWsCell.Row, LastColNewWs + 1) = _
Supplier
End If

Exit For
End If
Next NewWsCell

If FoundProduct = False Then
If IsEmpty(Cells(1, 1)) Then
Productrow = 1
Else
Productrow = LastRowNewWs + 1
End If

Reply
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Listing unique values, frequency, and maintaining list order integrity Alan[_13_] Excel Worksheet Functions 0 September 7th 11 06:58 PM
listing unique values AJSloss Excel Discussion (Misc queries) 1 November 11th 09 01:15 PM
FINDING AND LISTING UNIQUE DATA IN A COLUMN cncrouterman Excel Worksheet Functions 3 July 2nd 09 02:20 PM
listing unique entries from the entire worksheet markx Excel Worksheet Functions 3 February 15th 06 01:11 PM
Listing Unique Observations Henrik Excel Worksheet Functions 3 February 7th 05 11:16 PM


All times are GMT +1. The time now is 02:11 PM.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Copyright ©2004-2025 ExcelBanter.
The comments are property of their posters.
 

About Us

"It's about Microsoft Excel"