2011-10-14 45 views
3

对不起,这可能是一个极其基本的Excel VBA问题。我刚开始学习它,并且我没有发现很好的教程。我实际上找不到有关该语言的许多有组织的信息。Excel 2010 VBA引用其他工作表中的特定单元格

我有几张工作表叫做“Sheet1”和“Sheet2”。
Sheet1的第一列和第二列包含一些数字。

我想写一个宏,它打印一个函数的结果,其中包含2个变量(A列和B列各一个)到Sheet2。但我想将这些结果放在新工作表中,以便将Sheet1中'列'列的函数结果放入行1和列4 * i中。以下是我迄今为止所做的尝试,但它没有奏效,因为我不知道如何正确引用其他工作表中的特定单元格。

道歉,这是一个非常新的问题,任何帮助,非常感谢!

Sub results() 

    Dim i As Integer, noValues As Integer 
    noValues = Application.CountA(Range("A:A")) 

    Sheets("Sheet2").Select 
    Range("A1").Select 
    For i = 1 To noValues 
     Range("A1").Offset(0, 4 * (i - 1)).Select 
     ActiveCell.FormulaR1C1 = "=Sheet1!A[i] + Sheet1!B[i]" 
    Next i 

End Sub 

其中A [i]和B [i]应该表示列A或B第i行的值。

+2

只是一般提示为Excel。你几乎不需要“选择”或“激活”一个单元格,表单或任何东西。在你的例子中,你可以说Range(“A1”)。Offset(0,4 *(i-1))。formulaR1C1 =“你的公式”所有其他的东西是多余的,并减慢你的代码ALOT。 – TheFuzzyGiggler

回答

5
Sub Results2() 

    Dim rCell As Range 
    Dim shSource As Worksheet 
    Dim shDest As Worksheet 
    Dim lCnt As Long 

    Set shSource = ThisWorkbook.Sheets("Sheet1") 
    Set shDest = ThisWorkbook.Sheets("Sheet2") 

    For Each rCell In shSource.Range("A1", shSource.Cells(shSource.Rows.Count, 1).End(xlUp)).Cells 
     lCnt = lCnt + 1 
     shDest.Range("A4").Offset(0, lCnt * 4).Formula = "=" & rCell.Address(False, False, , True) & "+" & rCell.Offset(0, 1).Address(False, False, , True) 
    Next rCell 

End Sub 

循环遍历sheet1的A列,并为每个单元格的sheet2创建一个公式。要找到Sheet1中的最后一个单元格,我从底部(shSource.Rows.Count)和.End(xlUp)开始,以获取列中不是空白的最后一个单元格。

要创建公式的元素,我使用Sheet上单元格的Address属性。我正在使用Address的三个参数。前两个是RowAbsolute和ColumnAbsolute,都设置为false。我不在乎第三个参数,但是我将第四个参数(External)设置为True,以便它包含表单名称。

我更喜欢从源到目的地而不是其他方式。但这只是个人喜好。如果你想从目标工作,

Sub Results3() 

    Dim i As Long, lCnt As Long 
    Dim sh As Worksheet 

    lCnt = Application.WorksheetFunction.CountA(ThisWorkbook.Sheets("Sheet1").Columns(1)) 
    Set sh = ThisWorkbook.Sheets("Sheet2") 

    Const sSOURCE As String = "Sheet1!" 

    For i = 1 To lCnt 
     sh.Range("A1").Offset(0, 4 * (i - 1)).Formula = "=" & sSOURCE & "A" & i & " + " & sSOURCE & "B" & i 
    Next i 

End Sub 
+0

这正是我需要的,谢谢!我很惊讶没有无用的方法来循环访问列。我发现vba比C++或python更不直观,而且它更容易,不是吗?非常感谢! – Derek

2

我会给你一个简单的答案,希望能帮助你一般的VBA。学习VBA如何工作以及如何引用和访问元素的最简单方法是录制宏,然后在VBA编辑器中进行编辑。这就是我学习VBA的方式。它基于Visual Basic,所以VB的所有编程约定都适用。录制宏可让您了解如何访问和执行操作。

你可以使用这样的事情:

var result = 0 
Sheets("Sheet1").Select 
result = Range("A1").Value * Range("B1").Value 
Sheets("Sheet2").Select 
Range("D1").Value = result 

另外,您也可以参考使用Cells(1,1).Value这样你就可以设置变量,并根据需要增加它们的细胞。我想我只是不清楚你正在做什么,但我希望这有助于。

+0

我试过这个,但是当我录制一个宏时,我得到的都是相对单元格引用。所以如果我想从另一个单元格获得一个值,那么VBA录音只是沿着“将单元格向左4行,向下17行”这一行进行说明,而不是“取B20单元格”。 – Derek

+0

@Derek在录制宏时是否选择绝对或相对引用? – Fionnuala

+0

好点。但是这仍然不能帮助我运行诸如for循环之类的东西。可以说,我有一个已知数量的列都是任意长度的。我如何编写一个宏,在列的最后打印每列的长度? (我的意思是长度是列中非空单元格的数量)。 – Derek

0
Private Sub Click_Click() 

Dim vaFiles As Variant 
Dim i As Long 

For j = 1 To 2 
vaFiles = Application.GetOpenFilename _ 
    (FileFilter:="Excel Filer (*.xlsx),*.xlsx", _ 
    Title:="Open File(s)", MultiSelect:=True) 

If Not IsArray(vaFiles) Then Exit Sub 

With Application 
    .ScreenUpdating = False 
    For i = 1 To UBound(vaFiles) 
    Workbooks.Open vaFiles(i) 
    wrkbk_name = vaFiles(i) 
    Next i 
    .ScreenUpdating = True 
End With 

If j = 1 Then 
work1 = Right(wrkbk_name, Len(wrkbk_name) - InStrRev(wrkbk_name, "\")) 
Else: work2 = Right(wrkbk_name, Len(wrkbk_name) - InStrRev(wrkbk_name, "\")) 
End If 



Next j 

'Filling the values of the group name 

'check = Application.WorksheetFunction.Search(Name, work1) 
check = InStr(UCase("Qoute Request"), work1) 

If check = 1 Then 
Application.Workbooks(work1).Activate 
Else 
Application.Workbooks(work2).Activate 
End If 

ActiveWorkbook.Sheets("GI Quote Request").Select 
ActiveSheet.Range("B4:C12").Copy 
Application.Workbooks("Model").Activate 
ActiveWorkbook.Sheets("Request").Range("K3").Select 
ActiveSheet.Paste 


Application.Workbooks("Model").Activate 
ActiveWorkbook.Sheets("Request").Select 

Range("D3").Value = Range("L3").Value 
Range("D7").Value = Range("L9").Value 
Range("D11").Value = Range("L7").Value 

For i = 4 To 5 

If i = 5 Then 
GoTo NextIteration 
End If 

If Left(ActiveSheet.Range("B" & i).Value, Len(ActiveSheet.Range("B" & i).Value) - 1) = Range("K" & i).Value Then 
    ActiveSheet.Range("D" & i).Value = Range("L" & i).Value 
End If 

NextIteration: 
Next i 

'eligibles part 
Count = Range("D11").Value 
For i = 27 To Count + 24 
Range("C" & i).EntireRow.Offset(1, 0).Insert 
Next i 

check = Left(work1, InStrRev(work1, ".") - 1) 

'check = InStr("Census", work1) 
If check = "Census" Then 
workbk = work1 
Application.Workbooks(work1).Activate 
Else 
Application.Workbooks(work2).Activate 
workbk = work2 
End If 

'DOB 
ActiveWorkbook.Sheets("Sheet1").Select 
ActiveSheet.Range("D2").Select 
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select 
Selection.Copy 

Application.Workbooks("Model").Activate 
ActiveWorkbook.Sheets("Request").Select 
ActiveSheet.Range("C27").Select 
ActiveSheet.Paste 

'Gender 
Application.Workbooks(workbk).Activate 
ActiveWorkbook.Sheets("Sheet1").Select 
ActiveSheet.Range("C2").Select 
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select 
Selection.Copy 

Application.Workbooks("Model").Activate 
ActiveWorkbook.Sheets("Request").Select 
'Application.CutCopyMode = False 

ActiveSheet.Range("k27").Select 
ActiveSheet.Paste 

For i = 27 To Count + 27 
ActiveSheet.Range("E" & i).Value = Left(ActiveSheet.Range("k" & i).Value, 1) 
Next i 

'Salary 
Application.Workbooks(workbk).Activate 
ActiveWorkbook.Sheets("Sheet1").Select 
ActiveSheet.Range("N2").Select 
ActiveSheet.Range(Selection, Selection.End(xlDown)).Select 
Selection.Copy 

Application.Workbooks("Model").Activate 
ActiveWorkbook.Sheets("Request").Select 
'Application.CutCopyMode = False 

ActiveSheet.Range("F27").Select 
ActiveSheet.Paste 


ActiveSheet.Range("K3:L" & Count).Select 
selction.ClearContents 
End Sub 
+1

也许一些解释性文字可以很好地改善你的答案。 – wonko79

相关问题