使用excel vba无法在foreach循环中获取单元格值

时间:2015-05-06 12:07:18

标签: excel vba excel-vba excel-2010

enter image description here

您好, 我附上了图纸。 我的要求是:  我想得到所有的" G"与特定组织名称匹配的组织的列值(例如:360评估)。

我在G Column的第一次循环后得到空值

Sub UsageWeekTrend()

    Dim customerName As String
    Dim sheetName As String
    Dim dataFound As Boolean

    Dim selectedCell As Range
    Dim rowNumber As Integer
    Dim weekMinutes As Double

    Dim trendsFile As Workbook
    Dim trendsSheet As Worksheet

    On Error GoTo errorHandling

    sheetName = ActiveSheet.Name
    customerName = ActiveSheet.Range("A" & (ActiveCell.row)).Value
    dataFound = False

    For Each selectedCell In ActiveSheet.Range("A1:A1000")
     If UCase(selectedCell.Value) = UCase(customerName) Then
        weekMinutes = ActiveSheet.Range("G" & selectedCell.row).Value
        Debug.Print weekMinutes
        Debug.Print "G" & selectedCell.row

           If dataFound = False Then

                  If trendsFile Is Nothing Then
                     Set trendsFile = Workbooks.Add()
                     trendsFile.Activate
                     Set trendsSheet = trendsFile.ActiveSheet

                    Else
                       ' add a new sheet to the trends workbook
                        trendsFile.Activate
                        Set trendsSheet = Sheets.Add

                    End If

                dataFound = True
                rowNumber = 1
                trendsSheet.Name = Left(customerName, 10) + " " + Format(Date, "MMDD")
                trendsSheet.Cells(rowNumber, 1) = "Users"
                trendsSheet.Cells(rowNumber, 2) = "Minutes"
                rowNumber = rowNumber + 1

            End If

             ' if a sheet has been created, then we have at least one non-zero value so add data

             If dataFound = True Then
                trendsSheet.Cells(rowNumber, 1) = customerName
                trendsSheet.Cells(rowNumber, 2) = weekMinutes
                rowNumber = rowNumber + 1
             End If
       End If

  Next selectedCell

    ' if we have data, create the chart

    If dataFound = True Then

        ' make sure the trends sheet is active for chart insertion

        trendsSheet.Activate

        Dim chtChart As ChartObject
        Dim chartName As String
        Dim endRange As String

        ' define the end of the range for the chart

        endRange = "C" & CStr(rowNumber - 1)

        ' add chart to current sheet

        Set chtChart = ActiveSheet.ChartObjects.Add(Left:=200, Top:=200, Width:=900, Height:=400)
        chtChart.Activate
        ActiveChart.ChartType = xlLineStacked
        ActiveChart.SetSourceData Source:=trendsSheet.Range("A2", endRange)
        ActiveChart.HasTitle = True
        ActiveChart.ChartTitle.Text = customerName
        ActiveChart.ApplyLayout (5)


    Else
        MsgBox ("No usage data found for customer " + customerName)
    End If

    Exit Sub

errorHandling:
    MsgBox (Err.Description)


End Sub

2 个答案:

答案 0 :(得分:2)

当您运行此行时:

trendsFile.Activate

您更改Activesheet,因此第二次循环时再次查看活动表

weekMinutes = ActiveSheet.Range("G" & selectedCell.row).Value

但活动表已更改。我会将这些Activesheet调用更改为您在顶部指定的工作表对象。

对于刚接触VBA编程的人来说,这总是很好的阅读:How to avoid using Select in Excel VBA macros

答案 1 :(得分:1)

问题是您正在使用ActiveSheet,而且您的代码中的活动工作表正在更改。

执行trendsFile.Activate后,这两个引用会有新的含义ActiveSheet.Range("A1:A1000")ActiveSheet.Range("G" & selectedCell.row).Value

你已经创建了工作簿&您的Trends文件的工作表变量,并使用这些变量,您还需要为“源”工作表创建工作表变量(不确定如何引用它)。

另外,我对这部分代码有点担心:

If trendsFile Is Nothing Then
  Set trendsFile = Workbooks.Add()
  trendsFile.Activate
  Set trendsSheet = trendsFile.ActiveSheet
Else
  ' add a new sheet to the trends workbook
  trendsFile.Activate
  Set trendsSheet = Sheets.Add
End If

我相信你每次都会在循环中添加新的表格。

尝试这样的事情:

Sub UsageWeekTrend()

    Dim customerName As String
    Dim sheetName As String
    Dim dataFound As Boolean

    Dim selectedCell As Range
    Dim rowNumber As Integer
    Dim weekMinutes As Double

    Dim trendsFile As Workbook
    Dim trendsSheet As Worksheet
    Dim SourceSheet as worksheet 'this is the place where  you start, call it what you will 

    On Error GoTo errorHandling

    set SourceSheet = activesheet 'this will now always be THIS sheet, and won't change
    sheetName = SourceSheet.Name
    customerName = SourceSheet.Range("A" & (ActiveCell.row)).Value
    dataFound = False

    For Each selectedCell In SourceSheet.Range("A1:A1000")
     If UCase(selectedCell.Value) = UCase(customerName) Then
        weekMinutes = SourceSheet.Range("G" & selectedCell.row).Value
        Debug.Print weekMinutes
        Debug.Print "G" & selectedCell.row
        If dataFound = False Then
           If trendsFile Is Nothing Then
              Set trendsFile = Workbooks.Add()
              'trendsFile.Activate   - never needed
              Set trendsSheet = trendsFile.Sheets("Sheet1") 'use the first sheet, since you just created a brand new workbook
            Else
              ' add a new sheet to the trends workbook
              'trendsFile.Activate   -- you never need this when you're working with an object instead of "Active"
      'you'll find that this line will add a new sheet every time you execute the loop
      'once you've created your "trendsFile" workbook. you'll need to do some tweaking here
      'to prevent you getting one loop worth of data on each sheet
              Set trendsSheet = Sheets.Add
           End If
           dataFound = True
           rowNumber = 1
           trendsSheet.Name = Left(customerName, 10) + " " + Format(Date, "MMDD")
           trendsSheet.Cells(rowNumber, 1) = "Users"
           trendsSheet.Cells(rowNumber, 2) = "Minutes"
           rowNumber = rowNumber + 1
        End If

        ' if a sheet has been created, then we have at least one non-zero value so add data
        If dataFound = True Then
                trendsSheet.Cells(rowNumber, 1) = customerName
                trendsSheet.Cells(rowNumber, 2) = weekMinutes
                rowNumber = rowNumber + 1
        End If
     End If
  Next selectedCell

'The rest of your routine here...    

End Sub