2012-08-10 50 views
1

我伸出我的微距建设工作,组织和转变,从大型机检索到的数据生成的模板工作表。数据采用字符串形式,类似于here。我也在利用用SO建议开发的宏和这些问题的帮助(1)(2)。从数据表数据推入

我花了很多时间制定宏观的这个特定部分,在其他部分工作的同时点由于我在发展中遇到的困难 - 或许是由于缺乏经验。

说得简洁地说,我生成的工作表,重命名它们和推入的数据的工作表的那些,其被生成,然后填充空白表单。我试图在行的基础上做到这一点,因为每一行本质上是一个我正在推向工作表格的记录。有20个我正在使用的一些领域推向每个新的工作表。

我本来试图在高度嵌套循环,然后考虑怎么可能利用结构。然而,随着我越来越困惑,我转向了离散模型,因为我注意到我还没有想出如何正确使用Range对象的Cells(单元格地址属性)。

的代码如下:

'This subroutine is intended to take filtered data and use it to fill forms. 
'These forms use a very basic text template worksheet, which is copied over for each worksheet. 
'In general, these forms will number from 1 to 100, for discussion purposes. 
'The idea is that each row of data in the DataSheet will be used to fill each worksheet tab. 

Sub DataShifter() 


Dim RngOne As Range, RngCell As Range 
Dim RngTwo As Range 
Dim RngThree As Range, RngCell2 As Range 'RngCell2 is not currently in use 
Dim RngRow As Range 

Dim LastCell As Long 

Dim arrList() As String, LongCount As Long 

'Define range data within the Crtieria Sheet 
With Sheets("Criteria") 
    LastCell = .Range("A" & Sheets("Criteria").Rows.Count).End(xlUp).row 
    Set RngOne = .Range("A2:A" & LastCell) 
End With 

'Push values into the array 
LongCount = 0 
For Each RngCell In RngOne 
    ReDim Preserve arrList(LongCount) 
    arrList(LongCount) = RngCell.Text 
    LongCount = LongCount + 1 
Next 


'Filter the values to the desired criteria stored in the array. 
With Sheets("Sheet1") 

'For when this process is repeated. 
If .FilterMode Then .ShowAllData 

.Range("A:A").AutoFilter Field:=1, Criteria1:=arrList, Operator:=xlFilterValues 

End With 

'Add a Sheet to contain the filtered criteria 
Sheets.Add After:=Sheets(1) 
Sheets(2).Name = "DataSheet" 

'With the original dataset, snag all existing data based on the range in Sheet Criteria. 
'This avoids potential empty junk data and potential blanks pulled from the mainframe. 
With Sheets("Sheet1") 

LastCell = .Range("A" & Sheets("Criteria").Rows.Count).End(xlUp).row 
Set RngTwo = .Range("A2:AA" & LastCell) 

End With 

'Push data into DataSheet worksheet, so data is sequential 
Sheets(1).Select 
RngTwo.Copy 
Sheets("DataSheet").Select 
ActiveSheet.Paste 

'Define the ranges used within the sheet 
With Sheets("DataSheet") 
LastCell = .Range("A" & Sheets("Criteria").Rows.Count).End(xlUp).row 
Set RngThree = .Range("A2:A" & LastCell) 

End With 

'For each row in the range, (1) generate a new datasheet, and copy the form from the template to the new sheet. 
'(2) Rename the datasheet to be the value in Row 1, Column 1 ("A1"). 
'(3) Copy over information to the form based on column location in the Datasheet. 
'This method, even if made functional, is both procedural and limited in scope. Recursion with text matching will be the end goal for this form. 
For Each RngRow In RngThree.Rows 

Sheets.Add After:=Sheets(1) 

'Grab the text form from the Template and push it into the new sheet. 
Sheets("TemplateSheet2").Select 
Cells.Select 
Selection.Copy 
Sheets(2).Select 
ActiveSheet.Paste 

Sheets(2).Name = Sheets("DataSheet").Cells(RngRow, 1).Value 

Sheets(2).Range("B3") = Sheets("DataSheet").Cells(RngRow, 1).Value 
Sheets(2).Range("D3") = Sheets("DataSheet").Cells(RngRow, 2).Value 
Sheets(2).Range("F3") = Sheets("DataSheet").Cells(RngRow, 3).Value 
Sheets(2).Range("B5") = Sheets("DataSheet").Cells(RngRow, 4).Value 
Sheets(2).Range("B10") = Sheets("DataSheet").Cells(RngRow, 5).Value 
Sheets(2).Range("B7") = Sheets("DataSheet").Cells(RngRow, 6).Value 
Sheets(2).Range("D10") = Sheets("DataSheet").Cells(RngRow, 7).Value 
Sheets(2).Range("F10") = Sheets("DataSheet").Cells(RngRow, 8).Value 
Sheets(2).Range("B13") = Sheets("DataSheet").Cells(RngRow, 9).Value 
Sheets(2).Range("D13") = Sheets("DataSheet").Cells(RngRow, 10).Value 
Sheets(2).Range("F13") = Sheets("DataSheet").Cells(RngRow, 11).Value 
Sheets(2).Range("B16") = Sheets("DataSheet").Cells(RngRow, 12).Value 
Sheets(2).Range("D16") = Sheets("DataSheet").Cells(RngRow, 13).Value 
Sheets(2).Range("F16") = Sheets("DataSheet").Cells(RngRow, 14).Value 
Sheets(2).Range("B19") = Sheets("DataSheet").Cells(RngRow, 15).Value 
Sheets(2).Range("D19") = Sheets("DataSheet").Cells(RngRow, 16).Value 
Sheets(2).Range("F19") = Sheets("DataSheet").Cells(RngRow, 17).Value 
Sheets(2).Range("B21") = Sheets("DataSheet").Cells(RngRow, 18).Value 
Sheets(2).Range("D21") = Sheets("DataSheet").Cells(RngRow, 19).Value 
Sheets(2).Range("B23") = Sheets("DataSheet").Cells(RngRow, 20).Value 
Sheets(2).Range("D23") = Sheets("DataSheet").Cells(RngRow, 21).Value 

'Concatenate values from certain fields into one field 
Sheets(2).Range("B26") = Sheets("DataSheet").Cells(RngRow, 23).Value & Cells(RngRow, 24).Value & Cells(RngRow, 24).Value & Cells(RngRow, 25).Value & Cells(RngRow, 26).Value & Cells(RngRow, 27).Value 


Next RngRow 


End Sub 

目前,一个类型不匹配执行此代码的结果,第一行上84:Sheets(2).Name = Sheets("DataSheet").Cells(RngRow, 1).Value,然后在行进线路如果线84注释。我不确定我应该如何纠正这一点,以使我的代码有效运行,并且我正在要求解决这个特定问题。

更普遍关心的是我的方法,我会请也欢迎任何建议,意见,办法或改进,以考虑该宏 - 虽然修复是派诺蒙重要性之前,我进行任何形式的优化工作。

回答

3

在使用造成的错误RngRow.Row代替RngRow线。

RngRowRangeRngRow.Row将返回RngRow第一行的编号。

Cells预计RowIndex(一个数字)和一个ColumnIndex。当你提供一个Range(而不是一个数字)和一个ColumnIndex时,它会抛出你指定的类型匹配错误。

这里是你如何能缩短/提高你的代码,而不是一个例子:

Sheets.Add After:=Sheets(1) 
'Grab the text form from the Template and push it into the new sheet. 
Sheets("TemplateSheet2").Select 
Cells.Select 
Selection.Copy 
Sheets(2).Select 
ActiveSheet.Paste 

您应该能够使用相同的结果,虽然我会尽量避免select尽可能:

'Copy the Template into a new sheet. 
Sheets("TemplateSheet2").Copy After:=Sheets(1) 
Sheets(2).select 
+0

丹尼尔,你的解决方案工作得很好。至于缩短代码,我会尽量避免“选择”和不必要的冗长程序。 – JackOrangeLantern 2012-08-10 16:43:39