7

Ich bin auf der Suche nach einem Ratschlag für Methodik/Datenstruktur/algorithmischen Ansatz für ein Problem, das ich versuche zu lösen.Beratung über welche Methodik/Datenstruktur/Algorithmus zu verwenden

Ich schreibe eine benutzerdefinierte Tabellenkalkulation in VBA. Die Kalkulationstabelle ist eine Arbeitszeitplanung & Angebotsgenerierungsdokument. Der Benutzer gibt grundlegende Arbeitsablaufplanungsinformationen ein, die dann verwendet werden, um mehrere unterschiedliche Arbeitsblätter/Dokumente zu erzeugen, wobei die Quellendaten in einer Vielzahl von verschiedenen Layouts/Formaten präsentiert werden.

Um ehrlich zu sein, Excel ist die falsche Anwendung für diese, aber es ist, was die Benutzer wollten und sind bequem mit und ich kenne VBA ganz gut, so dass es ist, was ich feststecke.

Die Schlüsseldaten, die der Benutzer eingibt, sind im folgenden Format, im Wesentlichen ein Eintrag für jeden täglichen Arbeitsaufruf für jede Rolle.

╔═════╦════════╦════════════════╦════════════════╦═══════════════════╗ 
║ QTY ║ ROLE ║  START  ║  END  ║ DESCRIPTION  ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/15/17 08:00a ║ 6/15/17 04:00p ║ Travel to Prep ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/16/17 08:00a ║ 6/16/17 06:00p ║ Prep    ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/17/17 08:00a ║ 6/17/17 07:00p ║ Prep    ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 3 ║ Rigger ║ 6/18/17 06:00a ║ 6/18/17 05:00p ║ Travel to Install ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 3 ║ Rigger ║ 6/19/17 08:00a ║ 6/20/17 01:00a ║ Install   ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 3 ║ Rigger ║ 6/20/17 10:00a ║ 6/20/17 08:00p ║ Install   ║ 
╠═════╬════════╬════════════════╬════════════════╬═══════════════════╣ 
║ 3 ║ Rigger ║ 6/21/17 07:00a ║ 6/21/17 04:00p ║ Travel Home  ║ 
╚═════╩════════╩════════════════╩════════════════╩═══════════════════╝ 

Typischerweise sind die Daten mehrere Rollen über mehrere Tage und haben oft mehrere Instanzen einer Rolle auf einigen (aber nicht notwendigerweise alle) Tage.

Eine der Datenmanipulationen, die der Code ausführt, besteht darin, diese Quelldaten zu übernehmen und in einer Übersichtstabelle neu zu formatieren, damit der Benutzer zu einem späteren Zeitpunkt Namen zuweisen kann, sobald Personen zugewiesen sind. Es ist auch die Grundlage für verschiedene andere Einzelarbeit-Call-Blätter und Berechnung Anzahl der Flüge/Hotel-Nächte usw.

╔══════╦═══════════╦═════════╦═════════╦═══════════════════════════════════════╗ 
║ NAME ║ ROLE  ║ START ║ END  ║ DESCRIPTION       ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Rigger #1 ║ 6/15/17 ║ 6/21/17 ║ Trav | Prep | Trav | Install | Trav ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Rigger #2 ║ 6/18/17 ║ 6/21/17 ║ Trav | Install | Trav     ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Rigger #3 ║ 6/18/17 ║ 6/21/17 ║ Trav | Install | Trav     ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Sound  ║ 6/15/17 ║ 6/22/17 ║ Trav | Install | Trav     ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Crew #1 ║ 6/17/17 ║ 6/30/17 ║ Trav | Install | Show | Strike | Trav ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Crew #2 ║ 6/17/17 ║ 6/22/17 ║ Trav | Install | Trav     ║ 
╠══════╬═══════════╬═════════╬═════════╬═══════════════════════════════════════╣ 
║  ║ Crew #2 ║ 6/26/17 ║ 6/30/17 ║ Trav | Strike | Trav     ║ 
╚══════╩═══════════╩═════════╩═════════╩═══════════════════════════════════════╝ 

konvertiere ich die Quelldaten von n-Menge Zeilen in nx Reihen Menge 1 und fügen Sie eine Instanz Zählen Sie zum Rollenwert, wenn mehrere Instanzen vorhanden sind. Dies wird derzeit durch Einschleifen der Datenanordnung ein paar Mal erreicht und Manipulieren der Daten entsprechend - psuedocode unter

create 2-dimensional DataArray from source data 

Loop DataArray 
    generate list of unique Roles 
    Sum all Qty values 
Next 

Create 2-dimensional OutputArray 
    size rows to match Sum of all Qty values in DataArray 
    size cols to match DataArray cols 

//determine which UniqueRoles have multiple work instances 
For Each UniqueRole in DataArray 

    Loop DataArray 
     Count unique Start Dates for UniqueRole 
     Sum Qty values for UniqueRole 
    Next 

    If Sum of UniqueRole Qtys > Count of UniqueRole unique Start Dates Then 
     Add UniqueRole to MultpleInstanceList 
    End If 

Next UniqueRole 

//copy data into new array, expand all n-qty rows into n x rows of 1 qty 
Loop DataArray 

    Do While DataArray CurrentRow Qty Value > 1 
     Copy DataArray CurrentRow to OutputArray NewRow 
     Overwrite Qty value in OutputArray = 1 
     Reduce DataArray CurrentRow Qty value by 1 
    Loop 

    Copy DataArray CurrentRow to OutputArray NewRow 

Next 

//append count to Roles with multiple instances 
For Each UniqueRole in MultipleInstanceList 

    Loop OutputArray 
     generate list of unique Start Dates for current UniqueRole 
    Next 

    For Each StartDate in UniqueStartDates 

     Loop OutputArray 
      generate row index list for matching UniqueRole AND StartDate 
     Next 

     initialize counter k = 1 

     For Each Row in RowIndexList 
      OutputArray(Row) Role value = Role value & " #" & k 
      k = k + 1 
     Next Row 

    Next StartDate 

Next UniqueRoleVaue 

ich dann die Übersichtstabelle aus dem erweiterten Array erzeugen.

Dies funktioniert gut für einfache Fälle jedoch, wenn es komplexe Konfigurationen es inconsistant Ergebnisse produzieren kann, wenn die Instanznummer in Bezug auf die Beschreibung Wert Anhängen zB ...

╔═════╦════════╦═════════════════╦════════════════╦═══════════════════╗ 
║ QTY ║ ROLE ║ START   ║ END   ║ DESCRIPTION  ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/15/17 08:00a ║ 6/15/17 04:00p ║ Travel to Prep ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/16/17 08:00a ║ 6/16/17 06:00p ║ Prep    ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/17/17 08:00a ║ 6/17/17 07:00p ║ Prep    ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 3 ║ Rigger ║ 6/18/17 06:00a ║ 6/18/18 05:00p ║ Travel to Install ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 3 ║ Rigger ║ 6/19/17 08:00a ║ 6/19/17 06:00p ║ Install   ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 1 ║ Rigger ║ 6/20/17 07:00a ║ 6/20/17 04:00p ║ Travel Home  ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 2 ║ Rigger ║ 6/20/17 08:00a ║ 6/20/17 06:00p ║ Install   ║ 
╠═════╬════════╬═════════════════╬════════════════╬═══════════════════╣ 
║ 2 ║ Rigger ║ 6/21/17 07:00a ║ 6/21/17 04:00p ║ Travel Home  ║ 
╚═════╩════════╩═════════════════╩════════════════╩═══════════════════╝ 

... ausgeben wird ...

╔═══════════╦═════════╦═════════╦════════════════════════════════════════════╗ 
║ ROLE  ║ START ║ END  ║ DESCRIPTION        ║ 
╠═══════════╬═════════╬═════════╬════════════════════════════════════════════╣ 
║ Rigger #1 ║ 6/15/17 ║ 6/21/17 ║ Trav | Prep | Trav | Install | Trav | Trav ║ 
╠═══════════╬═════════╬═════════╬════════════════════════════════════════════╣ 
║ Rigger #2 ║ 6/18/17 ║ 6/21/17 ║ Trav | Install | Trav      ║ 
╠═══════════╬═════════╬═════════╬════════════════════════════════════════════╣ 
║ Rigger #3 ║ 6/18/17 ║ 6/20/17 ║ Trav | Install        ║ 
╚═══════════╩═════════╩═════════╩════════════════════════════════════════════╝ 

Diese gesamte Operation tritt während der normalen Dokumentverwendung mehrmals auf. Wenn sich die Datenreihenfolge ändert (was möglich ist), kann dies auch zu inkonsistenten Ergebnissen zwischen den Operationen führen.

Ich würde es vorziehen, das Quell-Array nicht als Teil der Operation zu sortieren, da es ein teurer Prozess ist, der merkliche Verzögerung hinzufügt, sobald die Tabelle in 10s von Zeilen kommt, selbst wenn Merge-Sort oder Quick-Sort verwendet wird.

Ich versuche, diesen Prozess so optimiert wie möglich zu halten; Viele andere Ausgänge verwenden dieses erweiterte Array, von denen einige effektiv Live-Feedback bieten. Daher wird der Vorgang jedes Mal ausgeführt, wenn der Benutzer Daten eingibt.

Die Liste der möglichen Beschreibungen, die der Benutzer auswählen kann, ist vorherbestimmt

╔═══════════════════════╗ 
║ Travel to Prep  ║ 
╠═══════════════════════╣ 
║ Travel & Prep   ║ 
╠═══════════════════════╣ 
║ Prep     ║ 
╠═══════════════════════╣ 
║ Prep & Travel   ║ 
╠═══════════════════════╣ 
║ Travel to Install  ║ 
╠═══════════════════════╣ 
║ Travel & Install  ║ 
╠═══════════════════════╣ 
║ Install    ║ 
╠═══════════════════════╣ 
║ Travel to Show  ║ 
╠═══════════════════════╣ 
║ Rehearsal    ║ 
╠═══════════════════════╣ 
║ Show     ║ 
╠═══════════════════════╣ 
║ Show & Dismantle  ║ 
╠═══════════════════════╣ 
║ Travel to Dismantle ║ 
╠═══════════════════════╣ 
║ Dismantle    ║ 
╠═══════════════════════╣ 
║ Travel Home   ║ 
╠═══════════════════════╣ 
║ Travel to Site Survey ║ 
╠═══════════════════════╣ 
║ Site Survey   ║ 
╠═══════════════════════╣ 
║ Dark Day    ║ 
╚═══════════════════════╝ 

Ich denkedies ist effektiv ein gerichteten Graphen, die alle eine Richtung haben Kanten (die meisten sind einfach) und einige Knoten können sich selbst loopen.Ich habe eine Adjazenzmatrix für die obige Liste erstellt, da dies ein logischer Weg zu sein scheint, um zu bestimmen, ob die Reihenfolge der Zuweisung gültig ist.

Gibt es eine effiziente Möglichkeit sicherzustellen, dass alle Pfade für eine bestimmte Rolle gültige Traversalpfade sind und wie die Rolleninstanznummern am besten neu zugewiesen werden, wenn ein oder mehrere Pfade nicht gültig sind?

Oder ist es möglich, die Untermenge von Beschreibungswerten auf jeder Ebene des Pfad-Traversals während des Erweiterungsvorgangs zu verwenden, um sicherzustellen, dass Rolleninstanznummern korrekt zugeordnet werden?

Gibt es ein bestimmtes Gebiet der Graphentheorie, das ich betrachten sollte? Sind Graphen hier der richtige Ansatz? Gibt es einen alternativen Ansatz, der effizienter wäre?

Jede Beratung/Hilfe wäre dankbar erhalten.

Dank

+3

Ich habe die Beschreibung 3 mal gelesen, aber welches Problem versuchen Sie eigentlich zu lösen? Wie sehen Ihre Daten aus Ihren Daten aus? Viele Male, wenn Sie Ihr Problem einem Fremden erklären können, haben Sie die Lösung. Das liest sich so, als ob du in einem wie steckst und das was vergisst. Können Sie einige Beispiele für Input, gute Ausgabe, falsche Ausgabe geben? – starmole

Antwort

0

Nun, Software in Office-Produkt, vor allem Excel integriert implementieren ist manchmal der Traum für die Benutzer. Das bedeutet nicht, dass Sie Code in eine spezielle Arbeitsblattdatei (.xlsm) schreiben sollten.

Sie haben andere Optionen, die die Trennung verbessern könnten und leicht in andere Lösungen übersetzt werden könnten. Einige Möglichkeiten:

1) ExcelAddIn in VBA: https://msdn.microsoft.com/en-us/library/office/gg597509%28v=office.14%29.aspx

2) ExcelAddIn in .NET: https://msdn.microsoft.com/en-us/library/cc668205.aspx

oder sogar

3) XLL, wenn die Leistung ist ein Problem (nicht scheint Ihr Fall zu sein) https://msdn.microsoft.com/en-us/library/office/bb687829.aspx

Ich hoffe, dass hilft!

1

Konzentration auf das folgende Zitat:

Ich würde es vorziehen, nicht die Quelle Array als Teil des Betrieb zu haben, zu sortieren, wie es ein teurer Prozess ist, der einmal merkliche Verzögerung fügt der Tabelle in 10s bekommt von Zeilen, auch bei Verwendung von merge-sort oder Quick-Sort.

Ich bemerke, dass Sie auf Ihre Quelle als ein Array beziehen. Also geben Benutzer Informationen in einen Tabellenbereich ein und von dort aus verwenden Sie VBA, um die Daten in ein Array zu laden? Wenn ja, frage ich mich, ob Sie Recordsets in VBA kennen. Aus meiner Erinnerung heraus sind sie nicht gerade einfach, Daten zu lesen, aber sobald die Daten vorliegen, können Sie eine SQL-Abfrage darauf ausführen. Das ist nicht gegen Performance-Probleme gefeit, aber ich denke, du wirst es besser machen, als einen Treffer nach 10er Platte zu machen. Und Sie werden sich wahrscheinlich keine Sorgen über Sortiermethoden machen müssen. Wenn Sie mit SQL nicht vertraut sind, würde ich sagen, dass es die Zeit auf jeden Fall wert ist, angesichts der Dinge, die Sie versuchen zu tun.

Here's ein Typ, der es getan hat. Er hatte einen anderen Grund dafür, aber Sie könnten es in Ihrem Fall anwenden.

Übrigens, wenn Ihre Benutzer sich mit Excel wohl fühlen, dann können sie sich mit der Arbeit immer noch wohlfühlen mit MS Access. Keine Installation neuer Software, Sie können SQL ausführen, ohne Daten in neue Objekte zu laden, und Sie können einfacher mit Formularen arbeiten und Berichte entwickeln.