7

我正在尋找一些關於方法/數據結構/算法的建議,以解決我正在嘗試解決的問題。關於使用什麼方法/數據結構/算法的建議

我正在VBA中編寫自定義電子表格應用程序。電子表格是一個勞動調度報表生成文檔。用戶輸入基本的人工調度信息,該信息隨後用於生成多個不同的工作表/文檔,其中源數據以各種不同的佈局/格式呈現。

說實話,Excel是錯誤的應用程序,但它是用戶想要和舒適的,我知道VBA很好,所以這是我堅持。

用戶輸入的關鍵數據是以下格式,實質上是每個角色的每個日常工作呼叫的條目。

╔═════╦════════╦════════════════╦════════════════╦═══════════════════╗ 
║ 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  ║ 
╚═════╩════════╩════════════════╩════════════════╩═══════════════════╝ 

通常情況下,數據是跨越多天的多個角色,並會經常有一些(但不一定是全部)天一個角色的多個實例。

代碼所做的其中一項數據操作是獲取此源數據並將其重新格式化爲彙總表,以便用戶在分配人員後可以在以後分配名稱。這也是其他各種個人工作呼叫表的基礎和航班的計算數量/酒店,晚上等

╔══════╦═══════════╦═════════╦═════════╦═══════════════════════════════════════╗ 
║ 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     ║ 
╚══════╩═══════════╩═════════╩═════════╩═══════════════════════════════════════╝ 

我從正貨行的源數據轉換成數量1 NX行追加一個實例如果存在多個實例,則計入角色值。下面

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 

僞碼然後我生成從膨脹陣列彙總表 - 這是目前通過相應地循環數據陣列幾次並操縱數據來實現的。

這工作正常進行簡單的情況下,然而當有複雜的配置附加相對描述值的實例數如...

╔═════╦════════╦═════════════════╦════════════════╦═══════════════════╗ 
║ 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  ║ 
╚═════╩════════╩═════════════════╩════════════════╩═══════════════════╝ 

...將輸出時,它會產生不一致的結果...

╔═══════════╦═════════╦═════════╦════════════════════════════════════════════╗ 
║ 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        ║ 
╚═══════════╩═════════╩═════════╩════════════════════════════════════════════╝ 

在正常文檔使用期間,整個操作會多次發生,如果數據順序發生變化(這是可能的),它也會在操作之間產生不一致的結果。

我不希望將源數組排序爲操作的一部分,因爲它是一個昂貴的過程,即使在使用合併排序或快速排序時,一旦表進入10幾行後就會增加明顯的滯後。

我試圖保持這個過程儘可能優化;許多其他輸出使用此擴展陣列,其中一些有效地提供實時反饋,因此每次用戶輸入數據時都會運行該操作。

使得用戶可以選擇可能的描述的列表是預先確定的

╔═══════════════════════╗ 
║ 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    ║ 
╚═══════════════════════╝ 

認爲這是有效的有向圖中,邊緣都具有一個方向(大多數是單程)和一些節點可以自行循環。我爲上面的列表建立了一個鄰接矩陣,因爲這似乎是確定賦值順序是否有效的合理方法。

是有保證的特定角色的所有路徑的有效方式是有效的遍歷路徑,以及如何在一個或多個路徑是無效的最好重新分配角色實例編號?

或者是有可能的擴展操作過程中使用的子集描述值在路徑遍歷每個級別,以確保角色實例編號是正確分配與開始?

我應該看看圖論的特定領域嗎?圖表是正確的方法嗎?有沒有其他方法可以工作/更高效?

任何建議/幫助將受到感謝。

感謝

+3

我讀了3次描述,但是你真的想要解決什麼問題?從您的數據中,您預期的數據是什麼?很多時候,如果你能向陌生人解釋你的問題,你將會得到解決方案。這讀起來就像你被困在一個怎樣並忘記了什麼。你能舉一些輸入,輸出好,輸出錯誤的例子嗎? – starmole

回答

0

好,部署軟件集成在Office產品,主要的Excel,有時是爲用戶的夢想。這並不意味着您應該將代碼寫入特定的電子表格文件(.xlsm)。

您有可以改善偏析,容易可以轉化成其他解決方案的其他選項。一些可能性:

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

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

甚至,

3)XLL,如果性能是一個問題(不似乎是你的情況)https://msdn.microsoft.com/en-us/library/office/bb687829.aspx

我希望幫助!

1

關注以下報價:

我不希望有源數組排序爲 操作的一部分,因爲它是一個昂貴的過程,增加了明顯的滯後,一旦 表進入10秒即使在使用合併排序或快速排序時也是如此。

我注意到,你指的是你的源數組。那麼用戶是否將信息輸入到工作表範圍內,然後使用VBA將數據加載到數組中?如果是這樣,我想知道你是否知道VBA中的記錄集。從我的回憶中,他們並不直接閱讀數據,但是一旦數據進入,您就可以在其上運行SQL查詢。這對性能問題來說不是免疫的,但我認爲你會比在10年的記錄之後獲得更好的效果。你可能不必擔心排序方法。如果你對SQL不熟悉,那麼肯定值得你嘗試做的事情。

Here's一個人做到了。他有不同的理由這樣做,但你可以將它應用於你的案例。

順便說一句,如果你的用戶習慣使用的Excel,然後工作,他們可能仍然是舒適的MS Access。不需要安裝新軟件,您可以在不將數據加載到新對象的情況下執行SQL,並且可以更輕鬆地處理表單和開發報告。