AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 76926888
Accepted
Thembelihle Sindiswa Sithole
Thembelihle Sindiswa Sithole
Asked: 2023-08-18 14:25:15 +0800 CST2023-08-18 14:25:15 +0800 CST 2023-08-18 14:25:15 +0800 CST

Pesquise uma string e os valores de saída correspondentes a essa string

  • 772

Bom dia

Meu objetivo é criar uma lista que cresça horizontalmente (por colunas). A Tabela 1 tem cinco colunas e um número de linhas sujeitas a aumento, (coluna A-tarefa principal), (coluna B-sub-tarefa), (coluna C- recurso 1 para realizar a tarefa),(coluna D- recurso 2 para realizar a mesma tarefa),(coluna E- recurso 3 para realizar a mesma tarefa). NB: Cada tarefa principal pode ter várias subtarefas, se for o caso, várias células (para a tarefa principal) serão mescladas para corresponder a várias subtarefas correspondentes à tarefa principal.

A Tabela 2 contém uma lista de todos os recursos listados na coluna A. Esses recursos podem ter/não ter aparecido na Tabela 2 (coluna C/D/E), ou seja, atribuídos a uma subtarefa/tarefa principal.

O código que tenho destina-se a pesquisar cada recurso na tabela 1, pesquisando tarefas e subtarefas às quais está atribuído e gerando esses resultados conforme mostrado na imagem.

O plano na criação do código é: O código deve usar nomes de recursos na coluna A-Tabela 2 como um índice, use-o para procurar o recurso na tabela 1 na primeira coluna, se encontrar uma correspondência, então valor de saída no mesa. E continua a procurar o mesmo recurso e saída se o encontrar. Em seguida, procure o mesmo recurso na próxima coluna e depois na próxima.

Uma vez terminada a busca pelo recurso aa, ele procura pelo recurso bb na coluna c, depois d e, por fim, na última. Inserindo valores de resultados à medida que avança.

Sua ajuda em modificar o que tenho é muito apreciada.

No código abaixo, as tabelas da tabela estão em planilhas diferentes. Isso é bom e pode ser implementado também.

Sub SearchResourceNames()
    
    'Declare variables
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim r As Range, c As Range, i As Long, j As Long, k As Long
    Dim resource As String, task As String, col As Long
    
    'Set the worksheets
    Set ws1 = ThisWorkbook.Sheets("Table1")
    Set ws2 = ThisWorkbook.Sheets("Table2")
    
    'Initialize variables
    i = 2
    j = 2
    k = 2
    col = 2
    
    'Loop through the resources in table 2
    For Each r In ws2.Range("A1:A10")
    
    'Get the resource name
    resource = r.Value
    
    'Initialize flag to indicate if task has been found
    found = False
    
    'Loop through the tasks in table 1
    For Each c In ws1.Range("A:A")
    
    'If the resource is found in the current task,
    If c.Value = resource Then
    
    'Set the flag to indicate that the task has been found
    found = True
    
    'Get the task name
    task = c.Offset(0, col).Value
    
    'If the task has not been found before,
    If Not ws2.Range("B" & k).Value = task Then
    
    'Add the task name to the output column
    ws2.Range("B" & k).Value = task
    
    'Increment the output column index
    k = k + 1
    
    End If
    
    End If
    
    Next c
    
    'If the task was not found in any of the tasks,
    If Not found Then
    
    'Print a message to the user
    MsgBox "The resource " & resource & " was not found in any of the tasks."
    
    End If
    
    Next r
    
    'Move to the next column in table 2
    col = col + 1
    
    'Reset the output column index
    k = 2
    
End Sub

Dados e saída desejada:

insira a descrição da imagem aqui

Saída atual indesejada

insira a descrição da imagem aqui

excel
  • 2 2 respostas
  • 36 Views

2 respostas

  • Voted
  1. Best Answer
    FunThomas
    2023-08-18T16:25:44+08:002023-08-18T16:25:44+08:00

    Eu sugeriria criar um Dicionário de todos os recursos. Cada entrada nesse Dicionário de recurso obtém novamente um Dicionário de todas as tarefas das quais o recurso precisa cuidar.

    Somente após a construção do Dicionário completo, ele será despejado na planilha de resultados.

    Se você não estiver familiarizado com Dicionários: Há muita documentação por aí, por exemplo aqui . Observe que estou usando ligação antecipada, portanto, você deve adicionar uma referência ao Microsoft Scripting Runtime.

    O código para construir o dicionário de recursos é bastante direto. Por motivos de velocidade, primeiro leio os dados completos Table1em uma matriz bidimensional (chamei-a de data). Em seguida, o código percorre todas as linhas de todas as colunas de recursos e lê o nome do recurso. Se não estiver no dicionário (é "novo"), criamos um novo Dicionário ( taskDict) para a entrada. Em seguida, a tarefa é adicionada ao Dicionário de tarefas e o recurso é adicionado ao Dicionário de recursos.

    Function fillResourceDict() As Dictionary
        
        ' (1) Read data from table1
        Dim data As Variant
        Dim lastRow As Long, row As Long
        Dim lastCol As Long, col As Long
        
        With ThisWorkbook.Sheets("Table1")
            lastRow = .Cells(.Rows.Count, 2).End(xlUp).row
            lastCol = .Cells(2, .Columns.Count).End(xlToLeft).Column
            
            data = .Range(.Cells(1, 1), .Cells(lastRow, lastCol))
            ' Fill in empty values in column 1 (because of the unholy merged cells)
            For row = 3 To lastRow
                If IsEmpty(data(row, 1)) Then data(row, 1) = data(row - 1, 1)
            Next row
        End With
    
        ' (2) Build the resouce-Dictionary. Loop over all recource columns
        Dim resourceDict As New Dictionary
        For row = 3 To lastRow
            For col = 3 To lastCol
                Dim resource As String, task As String, taskDict As Dictionary
                resource = data(row, col)
                If resource <> "" Then
                    If resourceDict.Exists(resource) Then
                        ' Read the taskDict from existing resource
                        Set taskDict = resourceDict(resource)
                    Else
                        ' New resource: Create a new Dictionary
                        Set taskDict = New Dictionary
                    End If
                    task = data(row, 1) & "-" & data(row, 2)
                    taskDict(task) = task    ' add Task
                    Set resourceDict(resource) = taskDict
                End If
            Next col
        Next row
                
        Set fillResourceDict = resourceDict
    End Function
    

    Agora tudo o que resta fazer é chamar esta função e preencher o resultado na tabela2:

    Sub fillToDoList()
        
        Dim resourceDict As Dictionary
        Set resourceDict = fillResourceDict
        
        With ThisWorkbook.Sheets("Table2")
            .UsedRange.ClearContents
            Dim resource As Variant, row As Long
            .Cells(1, 1) = "Resource"
            .Cells(1, 2) = "ToDo list"
            row = 2
            
            For Each resource In resourceDict.Keys
                .Cells(row, 1) = resource
                Dim taskDict As Dictionary
                Set taskDict = resourceDict(resource)
                .Cells(row, 2).Resize(1, taskDict.Count).Value = taskDict.Keys
                row = row + 1
            Next
        End With
    End Sub
    
    • 1
  2. VBasic2008
    2023-08-18T19:07:14+08:002023-08-18T19:07:14+08:00

    dados de transformação

    insira a descrição da imagem aqui insira a descrição da imagem aqui

    Option Explicit
    
    Sub GenerateResources()
        
        ' Constants
        
        Const SRC_SHEET As String = "Table1"
        Const SRC_MAIN_COLUMN As Long = 1
        Const SRC_SUB_COLUMN As Long = 2
        Const SRC_FIRST_DATA_CELL As String = "A2"
        Const DST_SHEET As String = "Table2"
        Const DST_FIRST_TABLE_CELL As String = "A1"
        Const DST_HEADERS As String = "Resource,To-Do List"
        Const DST_MAIN_SUB_DELiMiTER As String = "-"
    
        Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
        
        ' Source
        
        Dim sws As Worksheet: Set sws = wb.Sheets(SRC_SHEET)
        Dim sfCell As Range: Set sfCell = sws.Range(SRC_FIRST_DATA_CELL)
        
        Dim srg As Range:
        
        With sfCell.CurrentRegion
            Set srg = sfCell.Resize(.Row + .Rows.Count - sfCell.Row, _
                .Column + .Columns.Count - sfCell.Column)
        End With
    
        Dim scCount As Long: scCount = srg.Columns.Count
        
        If scCount < 3 Then
            MsgBox "Not enough columns.", vbCritical
            Exit Sub
        End If
        
        Dim srCount As Long: srCount = srg.Rows.Count
        Dim sData(): sData = srg.Value
        
        ' Unique resources to the keys, and the resources' rows to the keys
        ' of another (inner) dictionary held by each item of the outer dictionary.
        
        Dim rDict As Object: Set rDict = CreateObject("Scripting.Dictionary")
        rDict.CompareMode = vbTextCompare
        
        Dim sr As Long, sc As Long, rStr As String, rMaxCount As Long
        
        For sr = 1 To srCount
            For sc = 1 To scCount
                If sc <> SRC_MAIN_COLUMN And sc <> SRC_SUB_COLUMN Then
                    rStr = CStr(sData(sr, sc))
                    If Len(rStr) > 0 Then
                        If Not rDict.Exists(rStr) Then
                            Set rDict(rStr) = CreateObject("Scripting.Dictionary")
                        End If
                        If Not rDict(rStr).Exists(sr) Then
                            rDict(rStr)(sr) = Empty
                            If rDict(rStr).Count > rMaxCount Then
                                rMaxCount = rDict(rStr).Count
                            End If
                        End If
                    End If
                End If
            Next sc
        Next sr
        
        Dim dcCount As Long: dcCount = rDict.Count + 1
        
        If dcCount = 1 Then
            MsgBox "No resources found.", vbCritical
            Exit Sub
        End If
        
        ' Join mains and subs. Each row to the keys and each 'join' to the items
        ' of a dictionary
        
        Dim msDict As Object: Set msDict = CreateObject("Scripting.Dictionary")
        
        Dim mStr As String, cmStr As String, sStr As String, tStr As String
        Dim IsMainFound As Boolean
        
        For sr = 1 To srCount
            mStr = CStr(sData(sr, SRC_MAIN_COLUMN))
            If IsMainFound Then
                If Len(mStr) = 0 Then
                    mStr = cmStr
                Else
                    cmStr = mStr
                End If
                sStr = CStr(sData(sr, SRC_SUB_COLUMN))
                If Len(sStr) > 0 Then
                    tStr = mStr & DST_MAIN_SUB_DELiMiTER & sStr
                    msDict(sr) = tStr
                End If
            Else
                If Len(mStr) > 0 Then
                    IsMainFound = True
                    sr = sr - 1
                End If
            End If
        Next sr
        
        ' Using the information from the dictionaries,
        ' generate the destination (result) array.
        
        Dim dData(): ReDim dData(1 To msDict.Count + 1, 1 To dcCount)
        
        Dim dHeaders() As String: dHeaders = Split(DST_HEADERS, ",")
        dData(1, 1) = dHeaders(0)
        dData(1, 2) = dHeaders(1)
        
        Dim dr As Long: dr = 1
        
        Dim orKey, irKey, dc As Long
        
        For Each orKey In rDict.Keys
            dr = dr + 1
            dData(dr, 1) = orKey
            dc = 1
            For Each irKey In rDict(orKey).Keys
                If msDict.Exists(irKey) Then
                   dc = dc + 1
                   dData(dr, dc) = msDict(irKey)
                End If
            Next irKey
        Next orKey
    
        ' Destination
    
        Dim dws As Worksheet: Set dws = wb.Sheets(DST_SHEET)
        Dim dfCell As Range: Set dfCell = dws.Range(DST_FIRST_TABLE_CELL)
        Dim drg As Range: Set drg = dfCell.Resize(dr, dcCount)
        
        With drg
            
            ' Clear and write.
            .EntireColumn.Clear
            .Value = dData
            
            ' Format.
            
            ' Merge and center second header.
            With .Resize(1, dcCount - 1).Offset(, 1)
                .Merge
                .HorizontalAlignment = xlCenter
            End With
            ' All borders
            .Borders.Weight = xlThin
            ' All headers
            With .Resize(1)
                .Font.Bold = True
            End With
            ' All entire columns
            With .EntireColumn
                .AutoFit
                ' Resource columns only
                With .Resize(, dcCount - 1).Offset(, 1)
                    .ColumnWidth = 4
                End With
            End With
            ' Resource data only (no headers)
            With .Resize(dr - 1, dcCount - 1).Offset(1, 1)
                .HorizontalAlignment = xlCenter
            End With
            
            ' etc.
        
        End With
        
        MsgBox "Resources generated.", vbInformation
        
    End Sub
    
    • 0

relate perguntas

  • Existe uma maneira no Excel de contar as ocorrências de um texto específico em uma string, mas também incluir o caractere anterior?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve