2012-03-06 46 views
0

我嘗試使用EG獲取第一列的值並將0和列H,EG和0中的值相加,但遇到一些問題。總和將被置於列O行3.在檢查行和列後獲取數值總和時遇到問題

我試圖寫出代碼,找到名稱,EG和臨時0。不幸的是,代碼查找在列O中看到的最後0。如果您有任何想法,分享你的,會感謝你的幫助!謝謝!

enter image description here

Sub Macro1() 

    Dim LastRow1 As Long, RowG As Range, RowCheck As Long, Rowtosave As Long, LastCol1 As Long 
    Dim EGCheck As Long, ColEG As Range, firstEG As Long, IGCheck As Long, ColIG As Range 
    Dim findtemp As Range, tempRow As Long, tempRow1 As Long, lastEG As Long 
    Dim totalvalue As Long, valuestoadd As Long, tempCheck As Long 
    Dim emptycol As Long, empty1 As Range, Colempty As Long, tempcol As Long 

    LastRow1 = 50 
    LastCol1 = 50 

     For RowCheck = 1 To LastRow1 

      With Worksheets("Sheet1").Cells(RowCheck, 1) 
       If .Value = "Name" Then 

        Rowtosave = RowCheck 

       For EGCheck = 1 To LastCol1 

        With Worksheets("Sheet1").Cells(Rowtosave, EGCheck) 

        If .Value = "EG" Then 

        firstEG = EGCheck 

        End If 
        End With 

       Next EGCheck 

       For IGCheck = 1 To LastCol1 

        With Worksheets("Sheet1").Cells(Rowtosave, IGCheck) 

        If .Value = "IG" Then 

        lastEG = IGCheck - 1 

        End If 
        End With 

       Next IGCheck 

     End If 

     End With 

    Next RowCheck 

    'Look for temp 

    totalvalue = 0 

    For RowCheck = 1 To LastRow1 

     With Worksheets("Sheet1").Cells(RowCheck, 1) 
     If .Value = "temp" Then 

      tempRow1 = RowCheck 

       For tempCheck = 1 To lastEG 

       With Worksheets("Sheet1").Cells(tempRow1, tempCheck) 

       If .Value = "0" Then 

        tempcol = tempCheck 

       valuestoadd = Worksheets("Sheet1").Cells(tempRow1, tempcol).Select 

       totalvalue = totalvalue + valuestoadd 

       End If 
      End With 

       Next tempCheck 

      End If 
      End With 

     Next RowCheck 

    'Look for empty column 
     emptycol = 1 

     Do 

    Set empty1 = Worksheets("Sheet1").Cells(tempRow1, emptycol) 

     If empty1 = "" Then 

     emptycol = emptycol + 1 

     Colempty = emptycol 

     empty1 = totalvalue 

     End If 
    Exit Do 

    emptycol = emptycol + 1 

    Loop 

    End Sub 

追問:

什麼我的代碼需要做的是如下:

  1. 檢查行的 「名稱」。
  2. 發現「姓名」後,將尋找「EG」並將其設置爲第一個「EG」
  3. 然後,它會嘗試尋找第一「IG」,使我們可以有最後的第一個「EG」的(注:「EG」組BD列,IG組E列G列,第二EG組HJ等
  4. 之後,尋找溫度
  5. 然後找到0或100或整體,這將在列內從例如「EG」的類別,「第一個EG」到「第一個EG的最後一個」
  6. 然後添加1到行中,以便我們可以列出test1的總和
  7. 獲取0 「第一個EG(B列) 「和」第二個EG(H列)「,並將其放置在一個空列上,表示列O.對於該示例,結果將爲2+ 0 = 2

我意識到當我使用lastEG時引起的混淆。我對lastEG的意思是最後的EG EG

我希望能夠澄清疑惑。

與託尼討論並跟進改善問題

  • 沒有與A列中調用「名」這個名稱行的行。可能不需要在第一行。
  • 在名稱行中,存在包含「EG」的單元格。包含「EG」的細胞之後的幾個細胞是包含「IG」的細胞。從包含「EG」的單元格開始調用範圍,並繼續(但不包括)包含「IG」(EG範圍)的下一個單元格。在這個例子中,EG範圍是B:D和H:J。
  • A列中有一行帶有「temp」,將此稱爲Temp行。在這個例子中,Temp行緊接在Name行的下面,但顯然這不是必需的。名稱和臨時行可以出現在表格中的任何位置,名稱將始終高於臨時值,但這並不意味着它們已經配對在一起,有時我們可以有名稱,月份,臨時值。
  • 列A中有一行「test1」。調用此Test1行。
  • 在此示例中,Test1行立即位於Temp行下。該代碼不訪問Test1行。該解釋說,Temp行下的行是Test1行,但不會被檢查。
  • 在Temp行內的每個EG範圍內,都有一個包含'0','100'和'Overall'的單元格。零以下的單元格將爲空或包含數字。所有EG範圍的這些數字的值將被合計。該總數將被保存在臨時行下面的第一個空單元之後的單元格中,例如O3 - Q3中的值將放置在該單元格中。

我希望這會變得更好,託尼,我已經使用了一些你的觀點並編輯它。

+0

如果您正在循環查找值,那麼您可能希望在找到要查找的內容時使用「退出」。我試圖按照你的要求,但他們可以更清楚一點... – 2012-03-06 06:24:32

+0

@TimWilliams,我試過了,退出了,我不太確定哪個是它?你建議它應該在哪裏? – user1204868 2012-03-06 06:58:13

+0

要做的第一件事就是更新您的問題,並詳細解釋您希望代碼執行的操作。 – 2012-03-06 17:48:10

回答

1

我糾正了代碼中最明顯的錯誤,但對我來說沒有意義,所以我不知道它是否按照您的要求進行了操作。

' Option Explicit ensures that misspelt names are 
' not taken as an implicit declaration 
Option Explicit 
Sub Macro1() 

    ' This is legal syntax but I find it confusing. I only have two or more 
    ' variables in a Dim if they are closely related. 
    Dim LastRow1 As Long, RowG As Range, RowCheck As Long, Rowtosave As Long, LastCol1 As Long 
    Dim EGCheck As Long, ColEG As Range, firstEG As Long, IGCheck As Long, ColIG As Range 
    Dim findtemp As Range, tempRow As Long, tempRow1 As Long, lastEG As Long 
    Dim totalvalue As Long, valuestoadd As Long, tempCheck As Long 
    Dim emptycol As Long, empty1 As Range, Colempty As Long, tempcol As Long 

    ' You can nest Withs. 
    ' You only use one worksheet so let us declare that at the top. 

    With Worksheets("Sheet1") 

    ' These statements will have to be replaced when the number of rows and 
    ' columns exceed 50. 
    'LastRow1 = 50 
    'LastCol1 = 50 

    LastRow1 = .Cells.SpecialCells(xlCellTypeLastCell).Row 
    LastCol1 = .Cells.SpecialCells(xlCellTypeLastCell).Column 
    Rowtosave = 0 ' Initialise in case not found 
    For RowCheck = 1 To LastRow1 
     ' I use: With .Cells(R, C) 
     '   .Value = 5 
     '   .NumberFormat = "0.00" 
     '   .Font.Bold = True 
     '  End With 
     ' because I want to refer to .Cells(R, C) in several ways. 
     ' I do not see the benefit of: 
     ' With .Cells(R, C) 
     '  .Value = 5 
     ' End With 
     If .Cells(RowCheck, 1).Value = "Name" Then 
     Rowtosave = RowCheck 
     firstEG = 0  ' Initialise so you can test for 
     lastEG = 0  ' EG and IG not being found. 
     For EGCheck = 1 To LastCol1 
      If .Cells(Rowtosave, EGCheck).Value = "EG" Then 
      firstEG = EGCheck 
      ' Without the Exit For, the search will continue and 
      ' firstEG will identify the last EG not the first. 
      Exit For 
      End If 
     Next EGCheck 
     For IGCheck = 1 To LastCol1 
      If .Cells(Rowtosave, IGCheck).Value = "IG" Then 
      ' I find the name lastEG confusing 
      lastEG = IGCheck - 1 
      End If 
     Next IGCheck 
     ' If you really want the last IG on the row 
     ' better to search backwards. 
     For IGCheck = LastCol1 To 1 Step -1 
      If .Cells(Rowtosave, IGCheck).Value = "IG" Then 
      lastEG = IGCheck - 1 
      Exit For 
      End If 
     Next IGCheck 
     End If 
     ' I assume there is only one row with Name in column A 
     ' so there is no point in searching further. 
     Exit For 
    Next RowCheck 

    If Rowtosave = 0 Then 
     Call MsgBox("Name row not found", vbOKOnly) 
     Exit Sub 
    End If 
    If lastEG = 0 Then 
     Call MsgBox("EG not found on Name row", vbOKOnly) 
     Exit Sub 
    End If 

    'Look for temp 
    totalvalue = 0 
    tempRow1 = 0   ' Initialise in case not found 
    tempcol = 0 
    For RowCheck = 1 To LastRow1 
     If .Cells(RowCheck, 1).Value = "temp" Then 
     For tempCheck = 1 To lastEG 
      tempRow1 = RowCheck 
      ' I assume .Cells(tempRow1, tempCheck).Value is numeric. 
      ' If so "0" has to be converted to numeric for every test. 
      ' Better: If .Cells(tempRow1, tempCheck).Value = 0 Then 
      ' I might use "With .Cells(tempRow1, tempCheck)" because you 
      ' test its value then use the value. However, this code 
      ' makes no sense to me. 
      If .Cells(tempRow1, tempCheck).Value = "0" Then 
      ' Why are you saving tempcol? 
      tempcol = tempCheck 
      ' Why are you selecting valuestoadd? 
      ' You have not activated the sheet. You cannot select a 
      ' a cell except within the active worksheet. 
      'valuestoadd = .Cells(tempRow1, tempcol).Select 
      ' Why are you totalling all the cells with a value of zero. 
      totalvalue = totalvalue + .Cells(tempRow1, tempcol).Value 
      End If 
     Next tempCheck 
     ' I assume there is only one temp row 
     Exit For 
     End If 
    Next RowCheck 

    ' This loop appears to be searching for a empty cell 
    ' in which to place totalvalue. 

    'Look for empty column 
    emptycol = 1 
    Do 
     ' Why are you selecting the cell? 
     Set empty1 = .Cells(tempRow1, emptycol) 
     If empty1 = "" Then 
     ' Why are you place the value in the cell after the empty one? 
     emptycol = emptycol + 1 
     ' How will you use Colempty? 
     Colempty = emptycol 
     ' You cannot set a range to a numeric. 
     'empty1 = totalvalue 
     ' "empty1.Value = totalvalue" would be OK 
     .Cells(tempRow1, emptycol).Value = totalvalue 
     ' I have moved the Exit Do to inside the If. 
     ' Before "emptycol = emptycol + 1" could not be reached 
     Exit Do 
     End If 
     emptycol = emptycol + 1 
    Loop 

    End With 

End Sub 

響應user1204868的問題和新的闡釋新科

我開始回答你的問題,但我無法調和你給的所有信息。代碼,解釋和問題不一致。以下是我嘗試創建一致的描述。

  • 在列A中有一個名爲「Name」的行。調用這個Name行。
  • 在名稱行中,存在包含「EG」的單元格。包含「EG」的細胞之後的幾個細胞是包含「IG」的細胞。從包含「EG」的單元格開始調用範圍,並繼續(但不包括)包含「IG」(EG範圍)的下一個單元格。在這個例子中,EG範圍是B:D和H:J。
  • A列中有一行帶有「temp」,將此稱爲Temp行。在這個例子中,Temp行緊接在Name行的下面,但顯然這不是必需的。 「名稱」和「臨時」行可以出現在工作表內的任何位置,並可以按任意順序顯示
  • 列A中有一行「test1」。調用此Test1行。
  • 在此示例中,Test1行立即位於Temp行下。該代碼不訪問Test1行。該解釋說,Temp行下的行是Test1行,但不會被檢查。
  • 在Temp行內的每個EG範圍內,都有一個包含零的單元格。零以下的單元格將爲空或包含數字。所有EG範圍的這些數字的值將被合計。在Temp行中的第一個空單元格覆蓋任何現有值後,此總數將被保存在單元格中。在該示例中,Temp行中的第一個空單元格在N列中,因此總數將被保存在O列中,覆蓋現有的零。

我懷疑這個解釋是完全正確的。你應該把這個解釋複製到你的問題中並糾正它,這樣Tim或我或其他人就可以理解你真正想要的東西。

有關名稱行不是第1行的問題表明您擔心在開發工作表時名稱行可能會向下移動。您需要決定該工作表的修正情況以及可能發生的變化。例如,Test1行是否必須立即在Temp行之下?

A列中的「test2」和「test3」是什麼行?它們是否與Test1行相關?

在代碼中的註釋從testing1.xlsm

1期

您已刪除我的Option Explicit讓您有未聲明的變量。

地址:

Dim totalvalue1 As Long 
Dim totalvalue2 As Long 

第2期

.Cells(LastRow1, 1).Select 

只能選擇活動工作表中的單元格。我們正在使用With訪問工作表Sheet1,因此它不必處於活動狀態。

沒有必要選擇這個單元格,所以刪除這條語句。

3個

End If 
    ' I assume there is only one row with Name in column A 
    ' so there is no point in searching further. 
    Exit For 
Next RowCheck 

正如我在評論解釋,這個塊必須被替換爲:

Exit For 
    End If 
Next RowCheck 

第4期

For IGCheck = 1 To LastCol1 
    If .Cells(Rowtosave, IGCheck).Value = "IG" Then 
    lastEG = IGCheck - 1 
    Exit For 
    ElseIf .Cells(Rowtosave, IGCheck).Value = "EG" Then 
    lastEG = IGCheck - 1 
    'Exit For 
    ElseIf .Cells(Rowtosave, IGCheck).Value = "CG" Then 
    lastEG = IGCheck - 1 
    'Exit For 
    End If 
Next IGCheck 

我從這個猜想代碼和你前您正在搜索的名稱列的部分列planations其中包含「EG」細胞開始和結束一個欄前:

  • 含有「CG」細胞或
  • 接下來的下一列包含「EG」或
  • 含「IG」

我也想你已經註釋掉Exit For語句,因爲這個代碼不起作用細胞下一列的單元格的列。您的問題是For IGCheck = 1 To LastCol1。您在第1列開始搜索,因此您再次找到第一個「EG」。

替換的代碼塊有:

If firstEG = 0 Then 
    Call MsgBox("EG not found on Name row", vbOKOnly) 
    Exit Sub 
End If 
For IGCheck = firstEG + 1 To LastCol1 
    If .Cells(Rowtosave, IGCheck).Value = "IG" Or _ 
    .Cells(Rowtosave, IGCheck).Value = "EG" Or _ 
    .Cells(Rowtosave, IGCheck).Value = "CG" Then 
    lastEG = IGCheck - 1 
    Exit For 
    End If 
Next IGCheck 

5期

If lastEG = 0 Then 
    Call MsgBox("EG not found on Name row", vbOKOnly) 
    Exit Sub 
End If 

前面的問題下討論的代碼表明,EG的範圍可以由下一EG結束。這表明最終的EG範圍可以在使用範圍的末尾結束。

替換的代碼塊具有:

If lastEG = 0 Then 
    lastEG = LastCol1 - 1 
End If 

問題6

For n = 1 To LastRow1 
: 
Next 

整個代碼的第二塊是由這個For Loop包圍。用您的示例數據,這相當於For n = 1 to 5。在此代碼塊中,查找包含值「temp」的列A(RowCheck = 3)。然後您可以從RowCheck + n行訪問數據。也就是說,你訪問了第4到第8行。這真的是你想要做的嗎?

問題7

For tempCheck = 1 To lastEG 

我認爲這應該是:

For tempCheck = firstEG To lastEG 

第8

的第二個代碼塊是一個混亂。我可以看到代碼的作用,但我沒有理解爲什麼我很難評論。但是我會努力的。

環路尋找臨時行需要在外面所以像:

For RowCheck = 1 To LastRow1 
    If .Cells(RowCheck, 1).Value = "temp" Then 

    ' Set up new headers on Name row 
    ' Process all the test rows 

    Exit For 
    End If 
Next 

代碼上的Temp行上方的行放置一個「EG」。這假定Temp行上面的行是Name行。或者:

  • 臨時行始終將成爲名稱排在這種情況下,你不需要搜索的臨時行或
  • 你應該放在排Rowtosave的「EG」下面的一行。

無論哪個,你只需要做一次。

您不應該嘗試使用For n = 1 To LastRow1處理列A中帶有「testN」的行。選項包括:

  • 您已經使LastRow1比最後一行少了兩個。從初始化LastRow1的語句中刪除- 2。將For n = 1 To LastRow1替換爲For n = 1 To LastRow1 - tempRow1
  • 替換For n = 1 To LastRow1 ... Next帶Do循環一直持續到A列爲空或不包含「testN」或無論如何終止此表。
+0

嗨,謝謝你的回覆!對於「EG」,它從B列分到D,這就是爲什麼有第一個EG和LastEG。希望澄清疑問。我認爲我的代碼有很多問題。我添加了一個跟進我的問題。我希望你能明白我想要做什麼,並從那裏,也許你可以給我一些意見我做錯了什麼。謝謝! – user1204868 2012-03-07 00:43:10

+0

嗨,託尼,我已經解決了這個問題..但我面臨的另一個問題是,如果我要使用totalvalue = totalvalue +的東西,我可能會得到很多不同類型的totalvalue,因爲我必須列表通過行,你建議什麼? – user1204868 2012-03-07 05:53:25

+0

我意識到一個問題,也就是說,如果名字沒有發生在第一行,例如,發生在第二行,則會顯示未找到的消息名稱。我想知道爲什麼?如果你知道爲什麼,請告訴我。 – user1204868 2012-03-07 09:23:05

相關問題