返回列表 上一主題 發帖

[發問] 列出先進先出訊息

[發問] 列出先進先出訊息

各位大大


我想列出有顏色的部分訊息

要依流水號依序跟庫存取資料,每筆資料會獨立計算並消耗庫存數

請各位大大給我點提示,感謝

test.zip (10.14 KB)

回復 8# 准提部林


    謝謝論壇,謝謝前輩指導
後學藉此帖練習陣列與字典,學習方案如下,請前輩再指導

Option Explicit
Sub TEST()
Dim Arr, Brr, Crr, 需求&, Z, i&, j%, C%, T$, 庫存&, D As Date, W&, V&, R&
Set Z = CreateObject("Scripting.Dictionary")
Brr = Range([庫存!C1], [庫存!A65536].End(3))
For i = 2 To UBound(Brr)
   T = Trim(Brr(i, 1)): If T = "" Then GoTo i01
   If Not IsObject(Z(T)) Then Set Z(T) = CreateObject("Scripting.Dictionary")
   Z(T)(i) = 0: Z(T & "Tot") = Z(T & "Tot") + Val(Brr(i, 3))
i01: Next
Crr = Range([原始!C1], [原始!A65536].End(3))
ReDim Arr(2 To UBound(Crr), 1 To 100)
For i = 2 To UBound(Crr)
   T = Trim(Crr(i, 2)): 需求 = Val(Crr(i, 3)): C = 0: If Z(T & "Tot") = 0 Then GoTo i02
   For j = Z(T & "No") To Z(T).Count - 1
      W = W + 1: R = Z(Trim(Crr(i, 2))).keys()(j)
      庫存 = Val(Brr(R, 3))
      D = CDate(Brr(Z(Trim(Crr(i, 2))).keys()(j), 2))
      V = IIf(庫存 < 需求, 庫存, 需求)
      Arr(i, C + 1) = D: Arr(i, C + 2) = V: C = C + 2
      Z(T & "Tot") = Z(T & "Tot") - V
      需求 = 需求 - V: 庫存 = 庫存 - V
      If 庫存 = 0 Then Z(T & "No") = Z(T & "No") + 1 Else Brr(R, 3) = 庫存
      If 需求 = 0 Then Exit For
   Next
i02: If Z(T & "Tot") = 0 And 需求 > 0 Then Arr(i, C + 1) = "沒有資料": Arr(i, C + 2) = "數量不足"
Next
[原始!D2].Resize(UBound(Arr) - 1, UBound(Arr, 2)) = Arr
MsgBox "迴圈數:" & W
End Sub
用行動裝置瀏覽論壇學習很方便,謝謝論壇經營團隊
請大家一起上論壇來交流

TOP

本帖最後由 hcm19522 於 2024-1-31 17:10 編輯

(輸入編號10769-1) google網址:https://draft.blogger.com/blog/posts/9094075214774179359
google"EXCEL迷"  blog  或google網址:https://hcm19522.blogspot.com/

TOP

回復 11# n7822123


因對excel公式有些經驗, 所以程式碼中摻入了公式技巧,
雖然看起來短, 但效率及易讀性不一定就比較好!
其實程式碼最好是效率兼顧易讀性, 利于以後的修改。

因將變數定義為整數, 所以用val(???) 來避錯,
也可少一次IF的判斷~~ IF ISNUMERIC(ARR(I,3)) THEN

TOP

本帖最後由 n7822123 於 2020-4-4 05:19 編輯

回復 4# n7822123


看了準大寫的程式,我發現,我寫的還真是冗長.......

我也要學學只用字典紀錄列號,而不是把資料一股腦的塞進字典XD

不過準大用了不少小技巧,要讀懂可能比較難一點點

(如回讀第一列資料,用 val 函數把純字串變成數字0)

程式是依需求寫的,需求表達不清楚
或者沒有上傳附件,愛莫能助

TOP

回復 9# qaqa3296

If 庫存 = 0 Then TR(k) = ""
_如果庫存=0, 將原有[行號]變成空字符

xD(Brr(i, 1)) = Trim(Join(TR, " "))
__Join(TR, " ") 重新將split的陣列以[空白字元]組成字串
__Trim(Join(TR, " "))...利用Trim去掉字串前後的空白字元, 變成新字串(字串會越來越短,甚至為空)

TOP

回復 8# 准提部林

感謝准提部林大大提供其他方式

能稍微解釋新增這兩行的邏輯嗎?

If 庫存 = 0 Then TR(k) = ""
xD(Brr(i, 1)) = Trim(Join(TR, " "))

TOP

稍修一下, 若資料較多, 可減少不必要的迴圈:
Xl0000064-V2.rar (17.54 KB)

TOP

日期必須是由小而大排序的~~
程式碼簡化不了, 慢慢看吧!
  1. Sub TEST()
  2. Dim Arr, Brr, Crr, xD, i&, k%, R&, C%, 需求&, 庫存&, V&, TR, Mx&
  3. Set xD = CreateObject("Scripting.Dictionary")
  4. Arr = Range([庫存!C1], [庫存!A65536].End(xlUp))
  5. For i = 2 To UBound(Arr)
  6.     xD(Arr(i, 1)) = Trim(xD(Arr(i, 1)) & " " & i)
  7. Next i
  8. '---------------------------------
  9. Brr = Range([C2], [B65536].End(xlUp))
  10. ReDim Crr(1 To UBound(Brr), 1 To 100)
  11. For i = 1 To UBound(Brr)
  12.     C = 1:  需求 = Brr(i, 2)
  13.     TR = Split(Trim(xD(Brr(i, 1)) & " 1"), " ")
  14.     For k = 0 To UBound(TR)
  15.         庫存 = Val(Arr(TR(k), 3)):   If 庫存 = 0 Then GoTo k01
  16.         V = IIf(庫存 < 需求, 庫存, 需求)
  17.         Crr(i, C) = CDate(Arr(TR(k), 2)):  Crr(i, C + 1) = V
  18.         需求 = 需求 - V:   庫存 = 庫存 - V:   Arr(TR(k), 3) = 庫存
  19.         C = C + 2
  20. k01: Next k
  21.      If 需求 > 0 Then Crr(i, C) = "沒有資料": Crr(i, C + 1) = "數量不足"
  22. Next i
  23. [D2].Resize(UBound(Crr), 100) = Crr
  24. End Sub
複製代碼
Xl0000064.rar (14.91 KB)


================================

TOP

回復 4# n7822123

感謝 n7822123 大大的回復

這程式碼已達到需求

看起來淺顯易懂,正好可以學習一下

#也感謝ikboy大大的回復

刪除第二行依舊出現錯誤

執行階段錯誤'1004':

偵錯顯是在  .Resize(n, 3) = b 這行

但我看不懂ikboy大大的程式碼,所以無法自行除錯

TOP

        靜思自在 : 難行能行,難捨能捨,難為能為,才能昇華自我的人格。
返回列表 上一主題