使用来自数据行的ID堆叠成对的列

时间:2012-11-30 18:13:43

标签: ruby-on-rails ruby excel excel-vba sorting vba

您好我正在尝试对产品及其属性进行排序,但问题是属性的标头不是基于产品的名称和描述。例如,我有:

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

此行继续进行,直到该产品有许多属性。

我需要的东西会吐出来:

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

所以它看起来像这样:

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

有谁知道对这些信息进行排序的最佳方法是什么?

我一直在尝试使用一些excel vba脚本但是我想知道是否有一种方法可以用ruby来实现它,因为那是我现在正在学习的东西,这将是一个很好的真实世界的例子来深入研究进入红宝石。

3 个答案:

答案 0 :(得分:0)

您可以通过将属性分离到自己的模型中来大大简化此过程。

应用程序/模型/ product_attribute.rb

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

应用程序/模型/ 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

然后,您可以通过调用Product.sorted_attributes并编写视图代码来显示生成的2D数组,从而获得所需的信息。

答案 1 :(得分:0)

以下是John Bustos在评论中提到的充实版本。

我正在使用此示例数据(full workbook here

SampleData

我们的想法是使用VBA循环遍历列,并将它们输出到一个很长的瘦表中。

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

希望有所帮助!

答案 2 :(得分:0)

感谢您的帮助。我实际上已经知道了。我只是对lineemup宏进行了一些微调

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

其中6500表示数据集中的行数。