Макрос Copy Paste вызывает функциональность «сгруппированного» рабочего листа?

Я получаю сообщение об ошибке, которое я не могу понять:

После того, как я запускаю приведенный ниже макрос, два определенных строковых значения вставляются в одни и те же две ячейки на ВСЕХ листах, хотя я уверен, что листы не сгруппированы или не содержат собственного индивидуального кода. В частности, элементы «B12» и «B25» вставляются на всех страницах в одни и те же ячейки (A29 и A30) (см. код). «B12» и «B25» не имеют ничего общего с местоположением ячейки, а являются просто идентификаторами, уникальными для моего приложения. Это значения, которые копируются+вставляются с одного листа на другой. Если это ошибка копирования + вставки в коде, то я ожидаю, что все элементы будут иметь одну и ту же ошибку, потому что подпрограмма «алгоритм» вызывается для каждого листа.

Иногда это также происходит без выполнения макроса. И когда я пытаюсь отредактировать свою книгу до того, как она была до того, как поля были вставлены (щелкая каждую ячейку и вводя то, что было там раньше), она все еще вносит эти изменения во все листы, хотя я уверен, что они не сгруппированы или работающий код.

' Title: DSR AutoFill Macro

Sub autofill_DSR()

' Variable Declarations:

Dim x_count As Long
Dim n As Long
Dim item_a As String
Dim item_b As String
'Dim test_string As String

' Variable Initializations:

x_count = 0
Process_Control_NumRows = 15
Electrical_NumRows = 8
Environmental1_NumRows = 17
Env2_Regulatory_NumRows = 14
FIRE_NumRows = 15
Human_NumRows = 16
Industrial_Hygiene_NumRows = 16
Maintenance_Reliability_NumRows = 10
Pressure_Vacuum_NumRows = 16
Rotating_n_Mechanical_NumRows = 11
Facility_Siting_n_Security_NumRows = 10
Process_Safety_Documentation_NumRows = 3
Temperature_Reaction_Flow_NumRows = 18
Valve_Piping_NumRows = 22
Quality_NumRows = 10
Product_Stewardship_NumRows = 20
fourB_Items_NumRows = 28
'test_string = "NN"

' Main Data Transfer Code:

Sheets(Array("SUMMARY P.1", "SUMMARY P.2", "Process Control", _
"Electrical", "Environmental1", "Env.2 - Regulatory", "FIRE", _
"Human", "Industrial Hygiene", "Maintenance_Reliability", _
"Pressure_Vacuum", "Rotating & Mechanical", _
"Facility Siting & Security", "Process Safety Documentation", _
"Temperature-Reaction-Flow", "Valve-Piping", "Quality", _
"Product Stewardship", "4B ITEMS")).Select              'Create Array of all Sheets

'Sheets(Array("Sheet1", "Sheet2", "Sheet3")).Select     ' For testing

' Process Control Sheet:

    For n = 0 To (Process_Control_NumRows - 1)  'Cycle 16 times for each
                                                'item row in process controls tab
        Sheets("Process Control").Activate      'Choose specific sheet
        Range("D15").Select                     'Choose starting cell of "Yes" column

        Call Module2.algorithm(n, x_count)      'Call on subroutine (see algorithm code)

    Next n                                      'increment index to account for offset

' Electrical Sheet:

    For n = 0 To (Electrical_NumRows - 1)

        Sheets("Electrical").Activate
        Range("D15").Select

        Call Module2.algorithm(n, x_count)

        If (x_count > 21) Then                  'Abort autofill if too many items to hold
            Sheets("SUMMARY P.1").Activate      'on both summary pages put together (21 count)
            GoTo TooMany_Xs
        End If

    Next n

Это продолжается для всех листов...

' 4B ITEMS Sheet:

    For n = 0 To (fourB_Items_NumRows - 1)

        Sheets("4B ITEMS").Activate
        Range("D16").Select         ' NOTE: Starting cell is "D16"

        Call Module2.algorithm(n, x_count)

        If (x_count > 21) Then
            Sheets("SUMMARY P.1").Activate
            GoTo TooMany_Xs
        End If

    Next n

If (x_count > 5) Then               'Bring user back to last logged sheet

    Sheets("SUMMARY P.2").Activate

Else

    Sheets("SUMMARY P.1").Activate

End If

TooMany_Xs:
 If Err.Number <> 0 Then
    Msg = "you put more than 21 Items on the Summary Pages." & Chr(13) & _
        "Consider editing your DSR or taking some other action."
    MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
 End If

End Sub

И тогда этот следующий макрос находится в Module2:

Sub algorithm(n As Long, x_count As Long)

        'If an "x" or "X" is marked in the "Yes" column,
        'at descending cells down the column offset by the for loop index, n

        If (ActiveCell.Offset(n, 0) = "x" Or ActiveCell.Offset(n, 0) = "X") Then

            item_a = ActiveCell.Offset(n, -3).Value     ' Store Letter value
            item_a = Replace(item_a, "(", "")           ' Get rid of "(", ")", and " " (space)
            item_a = Replace(item_a, ")", "")           ' characters that are grabbed
            item_a = Replace(item_a, " ", "")

            item_b = ActiveCell.Offset(n, -2).Value     ' Store number value
            item_b = Replace(item_b, "(", "")           ' Get rid of "(", ")", and " " (space)
            item_b = Replace(item_b, ")", "")           ' characters that are grabbed
            item_b = Replace(item_b, " ", "")

            x_count = x_count + 1                       ' increment the total x count

            If (x_count > 5) Then                       ' If there are more than 5 "x" marks,

                Sheets("SUMMARY P.2").Activate          ' then continue to log in SUMMARY P.2
                Range("A18").Select                     ' Choose "Item" column, first cell
                ActiveCell.Offset((x_count - 6), 0).Value = (item_a & item_b)

                'Insert cocatenated value of item_a and item_b
                '(for example "A" & "1" = "A1")
                'at the cells under the "Item" column, indexed by x_count

            Else                                        ' If there are less than 5 "x" marks,

                Sheets("SUMMARY P.1").Activate          ' log in SUMMARY P.1
                Range("A25").Select
                ActiveCell.Offset((x_count - 1), 0).Value = (item_a & item_b)

            End If

        End If

Конец сабвуфера


person user2608147    schedule 29.07.2013    source источник


Ответы (2)


Выбирая все листы в вашем массиве, вы группируете их, и все, что вы пишете в ячейку на любом листе, будет записано на все листы.

Это виновник:

Sheets(Array("SUMMARY P.1", "SUMMARY P.2", "Process Control", _
"Electrical", "Environmental1", "Env.2 - Regulatory", "FIRE", _
"Human", "Industrial Hygiene", "Maintenance_Reliability", _
"Pressure_Vacuum", "Rotating & Mechanical", _
"Facility Siting & Security", "Process Safety Documentation", _
"Temperature-Reaction-Flow", "Valve-Piping", "Quality", _
"Product Stewardship", "4B ITEMS")).Select

Тот факт, что ваша проблема возникает, даже если опубликованный вами код не был запущен, заставляет меня думать, что после того, как вы выбрали все листы, происходит что-то еще.

Обратите внимание, что выбор и активация — действительно плохая идея. Объявляйте переменные для объектов, с которыми вы хотите работать, и взаимодействуйте с ними таким образом, вместо того, чтобы выбирать их.

Вот краткий пример того, как вы можете просмотреть все листы в книге и изменить их, не выбирая и не активируя. Вы можете изменить свой код, чтобы использовать этот шаблон:

Sub LoopThroughAllSheets()
    Dim wb As Workbook
    Dim ws As Worksheet

    Set wb = ThisWorkbook

    For Each ws In wb.Sheets
        ws.Range("D15").Value = ws.Name
    Next ws
End Sub

Прочтите следующее, чтобы начать писать более чистый и эффективный код VBA:

person Jon Crowell    schedule 29.07.2013
comment
Это великолепно, я понимаю этот код, и для меня это имеет смысл. Единственное, если мое начальное значение диапазона не всегда является ячейкой D15, как я могу изменить это, если я использую цикл for таким образом? - person user2608147; 29.07.2013
comment
Просто из интереса, если мы заполняем ВСЕ рабочие листы: Worksheets.FillAcrossSheets Range("D15:E20") просто убедитесь, что правильный лист активен. - person Andy G; 30.07.2013
comment
@ user2608147, начальный диапазон на каждом листе обычно определяется содержащимися в нем данными, которые, вероятно, со временем будут меняться. Вы можете найти последнюю строку или последний столбец или что-то еще, что вам нужно на каждом листе. - person Jon Crowell; 30.07.2013
comment
Как вы определяете, с какой ячейкой вы хотите работать на каждом листе? Это последняя ячейка в определенном столбце? Первая пустая ячейка в конце столбца? - person Jon Crowell; 30.07.2013
comment
Я просто собираюсь изменить рабочую книгу так, чтобы каждый лист начинался с D15 с интересующего меня столбца. Но как мне написать этот цикл for, чтобы я не перебирал каждый лист, а, скажем, листы 3-18 ( из 20) - person user2608147; 30.07.2013

Sheets(Array("SUMMARY P.1", "SUMMARY P.2", "Process Control", _
   "Electrical", "Environmental1", "Env.2 - Regulatory", "FIRE", _
   ...
"Product Stewardship", "4B ITEMS")).Select

группирует все эти рабочие листы. В какой-то момент вам нужно разгруппировать их, выбрав один рабочий лист:

Worksheets("Whatever").Select

Вы также должны проверить свой код, чтобы проверить, действительно ли необходимо группировать рабочие листы.

person Andy G    schedule 29.07.2013
comment
Итак, когда я пишу «Листы (электрические). Активировать», это не то же самое, что выбрать его? У меня все еще сгруппированы все остальные листы, даже если я напишу «.activate» для одного листа? - person user2608147; 29.07.2013
comment
Это верно. Можно выбрать несколько листов, и активация одного из них не приведет к отмене выбора (разгруппировке). Если вы сгруппируете несколько листов, обратите внимание, что одно из названий листов выделено жирнее других — это ActiveSheet. - person Andy G; 29.07.2013