Как я могу добавить новые строки, а затем вырезать / вставить в них данные? - PullRequest
0 голосов
/ 31 января 2020

Я работаю над большой таблицей. Это список имен работников и столбцов с номерами от 1 до 19. Каждое из этих чисел представляет определенную задачу.

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

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

Идея заключается в том, что, как только я В этом формате я могу использовать vlookup, чтобы заполнить задачу, над которой они работали, из другого набора данных в отдельный столбец.

снимок экрана электронной таблицы со скрытыми ненужными столбцами
Here is a screenshot of the spreadsheet, with unnecessary columns hidden

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

Мои знания по формулам в Excel в порядке, но мои знания по созданию макросов отсутствуют ,

1 Ответ

0 голосов
/ 31 января 2020

Вместо того, чтобы вставлять новые строки в существующий лист, создайте новый чистый лист с именем, например, «NEWDATA». Затем, отсканировав строки и столбцы часов от N до AF на исходном листе «ДАННЫЕ», создайте новую строку для NEWDATA, если часы> 0. Скопируйте строку в NEWDATA и удалите данные столбца часов. Затем в новой строке вставьте один столбец часов, которые вы сканируете. Вот пример кода для дальнейшей иллюстрации идеи. Также на другом новом листе под названием «НОРМАЛИЗОВАННЫЙ» создаются строки с 3 столбцами «Имя», «Задача» и «Часы».

Option Explicit
Sub normalize()

    Const COL_NAME As String = "K"
    Const HRS_START As String = "N"
    Const HRS_END As String = "AF"

    Dim wb As Workbook
    Set wb = ThisWorkbook

    ' sheet with source data
    Dim ws As Worksheet
    Set ws = wb.Sheets("DATA")

    ' new sheet
    Dim wsNEW As Worksheet
    Set wsNEW = wb.Sheets("NEWDATA")
    ws.Rows(1).EntireRow.Copy wsNEW.Cells(1, 1) ' copy header

    ' sheet to put normaized data
    Dim wsNormal As Worksheet
    Set wsNormal = wb.Sheets("NORMALIZED")
    wsNormal.Cells.Clear
    wsNormal.Range("A1:C1") = Array("Name", "Task", "Hours")

    ' create array of tasks from sheet header
    Dim arTasks As Variant
    arTasks = ws.Range(HRS_START & "1:" & HRS_END & "1").Value
    'Debug.Print "UBound(rngTask) = " & UBound(rngTasks, 2)

    Dim iLastRow As Long
    iLastRow = ws.Range(COL_NAME & Rows.count).End(xlUp).Row
    'Debug.Print "Last row = " & iLastRow

    ' declare variables
    Dim iRow As Long, iNewRow As Long, iCol As Integer, iColTask0 As Integer, cell As Range
    Dim sName As String, sTask As String, sngHrs As Single, count As Long
    iColTask0 = ws.Range(HRS_START & "1").Column - 1
    iNewRow = 1
    'Debug.Print "iColTask0", iColTask0

    ' scan the data
    For iRow = 2 To iLastRow
        sName = ws.Range(COL_NAME & iRow).Value
        For iCol = 1 To UBound(arTasks, 2)
            sngHrs = ws.Cells(iRow, iCol + iColTask0)
            sTask = arTasks(1, iCol)
            If sngHrs <> 0 Then
                iNewRow = iNewRow + 1

                ' 3 columns of normalised data
                With wsNormal.Cells(iNewRow, 1)
                   .Offset(0, 0) = sName
                   .Offset(0, 1) = sTask
                   .Offset(0, 2) = sngHrs
                End With

                ' copy row
                ws.Range("A" & iRow & ":" & HRS_END & iRow).Copy wsNEW.Range("A" & iNewRow)
                ' blank hours
                wsNEW.Range(HRS_START & iNewRow & ":" & HRS_END & iNewRow).Value = ""
                ' insert hours for task
                wsNEW.Cells(iNewRow, iCol + iColTask0) = sngHrs

               'Debug.Print iRow, sName, sTask, sngHrs
            End If
        Next
    Next

    ' result
    Dim msg As String
    msg = iLastRow - 1 & " rows scanned on " & ws.NAME & vbCrLf & _
    iNewRow - 1 & " rows created on " & wsNEW.NAME
    MsgBox msg, vbInformation

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...