简体   繁体   中英

stacking pairs of columns with ids from rows of data

Hi I'm trying to sort products and their attributes but the problem is that the headers for the attributes are not based on the name and description of the product. So for example I have:

Product id | attribute 1 name | attribute 1 desc | attribute 2 name | attribute 2 desc
1001       | screen size      | 15"              | DCR              | 10,000:1
1002       | DCR              | 200,000:1        | Widescreen       | yes

This row goes on until however many attributes there are for the product.

What I need is something that would spit out:

Product id, attribute 1 name, attribute 1 desc
Product id, attribute 2 name, attribute 2 desc

So it would look like this:

1001, screen size, 15"
1001, DCR, 10,000:1
1002, DCR, 200,000:1
1002, widescreen, yes

Does anyone know what would be the best way to sort this information?

I've been trying with a bit of excel vba scripts but I was wondering if there was a way of doing it with ruby since that's what I'm learning right now and it would be a good real world example to delve deeper into ruby.

You can simplify this process greatly by separating the attributes into their own model.

app/models/product_attribute.rb

class ProductAttribute < ActiveRecord::Base
  attr_accessible :name, :desc, :product_id
  belongs_to :product
  #...
end

app/models/product.rb

class Product < ActiveRecord::Base
  # ...
  has_many :product_attributes
  # ...

  def self.sorted_attributes
    Product.all.collect{|prod| prod.sorted_attributes}
  end      

  def sorted_attributes
    product_attributes.all(order: "name ASC").collect{|attr| [self.id, attr.name, attr]}
  end
end

You would then be able to get the information you require by calling Product.sorted_attributes and writing view code to display the resulting 2D array.

Here is a fleshed out version of what John Bustos mentioned in the comments.

I'm working with this sample data ( full workbook here )

样本数据

The idea is to use VBA to loop through pairs of columns, and output them in a long skinny table.

Sub MakeSkinny()
    Dim rng As Range
    Dim clOutput As Range
    Dim cl As Range

    Set rng = Range("A3").CurrentRegion ' raw data'
    Set clOutput = Range("A9") ' Where to output results'

    Set cl = clOutput
    ' Add headers to the new table'
    cl.Offset(0, 0).Value = "Item"
    cl.Offset(0, 1).Value = "Attribute"
    cl.Offset(0, 2).Value = "Value"
    Set cl = cl.Offset(1, 0) ' go to the next row of output'

    For i = 2 To rng.Rows.Count
        iCol = 2 ' Start at column 2'
        Do Until iCol >= 7 ' set to however many cols you have'
            'Check for blank attribute name'
            If rng.Cells(i, iCol) <> "" Then
                cl.Offset(0, 0) = rng.Cells(i, 1) ' Item ID'
                cl.Offset(0, 1) = rng.Cells(i, iCol) ' Attribute Name'
                cl.Offset(0, 2) = rng.Cells(i, iCol + 1) ' Attribute Value'
                Set cl = cl.Offset(1, 0) ' go to the next row of output'
            End If
            iCol = iCol + 2 'Advance to next set of attributes'
        Loop
    Next i
End Sub

Hope that helps!

Thanks for the help. I actually figured it out a while ago. I just made some slight adjustments to the lineemup macro

Sub lineemupSAS()

Dim i As Long

Dim dr As Long

For i = 2 To Cells(2, Columns.Count).End(xlToLeft).Column Step 2

dr = Cells(Rows.Count, 1).End(xlUp).Row + 1

Cells(2, 1).Resize(6500).Copy Cells(dr, 1)

Cells(2, i).Resize(6500).Copy Cells(dr, 2)

Cells(2, 1 + i).Resize(6500).Copy Cells(dr, 3)

Next i

End Sub

Where 6500 represents the number of rows in the dataset.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM