Tính sở hữu chéo công ty (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

maiphuonggif

Thành viên mới
Tham gia
21/12/20
Bài viết
4
Được thích
0
Kính gửi anh chị,

Em đang bế tắc về 1 vấn đề tính sở hữu chéo ( cụ thể em có ví dụ trong file đính kèm hoặc anh chị có thể xem hình dưới)
E ko dùng hàm thông thường được vì logic nó hơi rối , nên nhờ anh chị xem thử sử dụng VBA cho việc tính sở hữu chéo gián tiếp và trực tiếp .
Bảng dữ liệu gốc của em là bảng ( 80 * 80 ) ,nên em chỉ ví dụ trong file đơn giản cho đỡ rối ạ

Cảm ơn anh chị.

1608546626411.png
 
Cái này mà tính được thì đem bán bản quyền cho mấy cơ quan kiểm soát tập đoàn.
 
Upvote 0
Ví dụ trong hình mới thấy xuôi, chưa thấy ngược và vòng tròn.
- A sở hữu B và C
- C sở hữu E
- E sở hữu 1 phần của A
Bài toán này không phải khó mà là rất khó. Ngoài chuyện tính đúng theo logic còn phải tính đúng theo luật hiện hành.
 
Upvote 0
Ví dụ trong hình mới thấy xuôi, chưa thấy ngược và vòng tròn.
- A sở hữu B và C
- C sở hữu E
- E sở hữu 1 phần của A
Bài toán này không phải khó mà là rất khó. Ngoài chuyện tính đúng theo logic còn phải tính đúng theo luật hiện hành.
Mấy tập đoàn lớn có cách quản lý cái này. Và trên thực tế, họ vẫn "sở hữu tùm lum" đều đặn. Chỉ là mấy cơ quan kiểm soát của nhà nước chạy theo không kịp chúng thôi, cho nên chúng vẫn qua mặt. Vì vậy, ở bài #2 tôi mới nói người nào làm được cái này thì bán cho cơ quan nhà nước.
 
Upvote 0
Nếu không có sở hữu ngược và sở hữu vòng tròn thì dùng thuật toán tương tự bài toán tính nguyên vật liệu SX nhiều công đoạn, công đoạn sau lấy bán thành phẩm đầu ra của công đoạn trước làm đầu vào của mình.
 
Upvote 0
Nếu không có sở hữu ngược và sở hữu vòng tròn:
Bảng 80x80 phải chuyển thành 600x2, chỉ công ty nào có cty con mới liệt kê

1608569357090.png

Điền tên các công ty cần tính vào 2 cột A và B, Nhấn nút Run và xem kết quả:

1608604600243.png

Nếu dữ liệu nhiều sẽ tối ưu code theo mẫu của anh @HieuCD
 
Lần chỉnh sửa cuối:
Upvote 0
Nếu không có sở hữu ngược và sở hữu vòng tròn thì dùng thuật toán tương tự bài toán tính nguyên vật liệu SX nhiều công đoạn, công đoạn sau lấy bán thành phẩm đầu ra của công đoạn trước làm đầu vào của mình.
A sở hữu trực tiếp E thì => E không thể sở hữu lại % nào của A hết bác ạ
A sở hữu gián tiếp E thì vẫn có thể ạ
 
Upvote 0
@ tác giả bài #10.
Loại này phải tính bằng B-Tree (cây nhị phân). Vì VBA không hổ trợ cấu trúc linked list (nói cho đúng thì có, nhưng cái SinglyLinkedNodes rất khó xài). Cho nên bắt buộc phải dùng bảng tính để lập B-Tree. Tương tự như cách spider các thư mục của bài toán liệt kê folders và subfolders, bài này dùng đệ quy là dễ nhất.
 
Upvote 0
@ tác giả bài #10.
Loại này phải tính bằng B-Tree (cây nhị phân). Vì VBA không hổ trợ cấu trúc linked list (nói cho đúng thì có, nhưng cái SinglyLinkedNodes rất khó xài). Cho nên bắt buộc phải dùng bảng tính để lập B-Tree. Tương tự như cách spider các thư mục của bài toán liệt kê folders và subfolders, bài này dùng đệ quy là dễ nhất.
File mấy bài trên (đã xoá), và file bài 10 đã có đệ quy đó anh, nhưng chưa tính trường hợp sở hữu vòng tròn.
 
Upvote 0
Sởi hữu vòng tròn chỉ xét để tình giá trị công ty, và bài tính ấy rất phức tạp.
Nếu chỉ tính bản đồ hoạt động của công ty thì cây nhị phân tính tới chỗ vòng là ngừng nhánh ấy lại.

Chú: bản đồ hoạt động gồm địa hình địa lý, địa hình sản phẩm, dịch vụ... Để tính chính xác còn phải thêm định nghĩa sở hữu bao nhiêu phần trăm thì được coi như gồm vào bản đồ của công ty chính. Ví dụ công ty A chuyên dịch vụ tài chính, sở hữu 20% công ty B chuyên nuôi gà. Tuỳ theo luật lệ của nước mà A đăng ký mà A có thể chọn khai mình làm cả tài chính lần nuôi gà hay chỉ tài chính (công ty B chỉ là đầu tư tài chính của A. A không dính dáng gì đến quản lý). Lưu ý là luật thương mãi nhiều nước rất rõ rệt rằng "dính dáng quản lý" không nhất thiết phải làm chủ trên nửa cổ phiếu. Nếu thị trường hoặc nhà nước có lý do để tin rằng mình có ảnh huổng lớn (lưu ý "lớn") trong quản lý công ty là có "dính dáng quản lý". Một số nước đặt ra trên 30% phải tự chứng minh rằng mình "không dính líu quản lý" bằng cách phó nhiệm các phiếu bầu.
 
Upvote 0
Sở hữu vòng tròn chỉ xét để tình giá trị công ty, và bài tính ấy rất phức tạp.
Trước mắt chỉ tính để chia cổ tức thôi cũng đủ mệt rồi anh ạ.
Theo tôi (chưa biết đúng hay sai), sẽ có ít nhất 2 cách tính:
- Tính đơn giản: Tính độc lập A sở hữu E bao nhiêu và tính độc lập E sở hữu A bao nhiêu rồi cấn trừ nhau
- Tính vòng tròn: Tính lặp cho đến khi đạt sai số (hay phương sai gì gì đó) chấp nhận được. Phải đệ quy lần 2 hoặc lặp Do

Mà nếu tôi lập luận sai cũng không sao, vì đúng cũng chưa chắc làm được
 
Upvote 0
Trước mắt chỉ tính để chia cổ tức thôi cũng đủ mệt rồi anh ạ.
Theo tôi (chưa biết đúng hay sai), sẽ có ít nhất 2 cách tính:
- Tính đơn giản: Tính độc lập A sở hữu E bao nhiêu và tính độc lập E sở hữu A bao nhiêu rồi cấn trừ nhau
- Tính vòng tròn: Tính lặp cho đến khi đạt sai số (hay phương sai gì gì đó) chấp nhận được. Phải đệ quy lần 2 hoặc lặp Do

Mà nếu tôi lập luận sai cũng không sao, vì đúng cũng chưa chắc làm được
Tình vòng tròn là phép cộng dãy số hội tụ có công thức nhưng lâu quá không nhớ, code chạy vòng Do đến khi chênh lệch kết quả < giá trị qui định thì dừng
 
Upvote 0
Ủa sao giống cấu trúc kiểu bán hàng đa cấp vậy chú Mỹ :xmasbiggrin:
Sở hữu cổ phần. Khi sở hữu cổ phần lớn hơn 1 tỷ lệ nào đó theo điều lệ thì được quyền tham gia hội đồng quản trị (được bỏ phiếu trong các cuộc họp), hơn 1 tỷ lệ nào đó theo điều lệ thì được tham gia quản lý. Nhưng bất kỳ tỷ lệ nào cũng được chia cổ tức (lãi) hàng năm.
Chả có gì giống bán hàng đa cấp
 
Upvote 0
Đó là vòng tròn. Và chưa thể tính được
Tình vòng tròn là phép cộng dãy số hội tụ có công thức nhưng lâu quá không nhớ, code chạy vòng Do đến khi chênh lệch kết quả < giá trị qui định thì dừng
Cái này hình như em Vân nhớ anh Hiếu từng viết 1 bài dạng tương tự liên quan đến bán Thành Phẩm đúng không anh ?
 
Upvote 0
Upvote 0
Lần chỉnh sửa cuối:
Upvote 0
Có gì đó sai sai về thực tế. Hình như tác giả đang mặc định giá trị của các cty là như nhau?
B chiếm 40% của D
D chiếm 60% của E
suy ra B chiếm 24% của E? Tức là đang mặc định giá trị D = E?
Giả sử D là GPE và E là tập đoàn Microsoft thì kết quả có còn đúng không?
 
Upvote 0
Có gì đó sai sai về thực tế. Hình như tác giả đang mặc định giá trị của các cty là như nhau?
B chiếm 40% của D
D chiếm 60% của E
suy ra B chiếm 24% của E? Tức là đang mặc định giá trị D = E?
Giả sử D là GPE và E là tập đoàn Microsoft thì kết quả có còn đúng không?
Giả sử D phát hành 1 tỷ đồng cổ phiếu, B mua 40% tức là 400 tr
E phát hành 500 triệu đồng cổ phiếu, D mua 60% tức là D sở hữu 300 tr.
Nhưng trong 300 tr đó có phần của B là 40% -> 120 tr
Vậy B có trong E thông qua D là 120 tr, và 120 tr này tương ứng 24% của 500 tr

khi chia cổ tức của E cho D 100 tr, thì D không hưởng hết, mà phải chia lại cho B 40% = 40 tr.

B sở hữu gián tiếp E thông qua D, chỉ dùng để tính giá trị và chia cổ tức, không được quyền quản lý vì trong tay không có cổ phần. Muốn tham gia quản lý E chẳng hạn bắt E bỏ nuôi gà sang nuôi cọp, phải ép D theo ý B để D ép E
 
Upvote 0
E thì không rành lập trình , nên có nhờ 1 ng bạn viết bên Python, cũng dùng map hay đệ quy gì đó thì phải. Gửi cho các a/chị tham khảo (e thì đọc cũng như mù ) :))) e chỉ biết đọc code VBA tí tẹo thôi

@ptm0412 Thanks bác , để e đọc thử . file bác up lại e thấy đúng số.
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
Thử viết Sub đệ quy, mượn file của bạn @ptm0412
Mã:
Dim sArr(), Res(), Dic As Object

Sub XYZ()
  Dim CT$, CTName$, sRow&, i&, k&
 
  Set Dic = CreateObject("scripting.dictionary")
  CT = Sheet2.Range("A4").Value
  sArr = Sheet1.Range("A2", Sheet1.Range("E65000").End(xlUp)).Value
  sRow = UBound(sArr)
  ReDim Res(1 To sRow, 1 To 3)
 
  For i = 1 To UBound(sArr)
    If sArr(i, 1) = CT Then CTName = sArr(i, 2)
    Dic.Item(sArr(i, 1)) = Dic.Item(sArr(i, 1)) & "|" & i
    Dic.Item(sArr(i, 1) & "|" & sArr(i, 3)) = sArr(i, 5)
  Next
  If Dic.exists(CT) Then Call CTyCon(k, CT, Split(Dic.Item(CT), "|"), 1)
 
  Sheet2.Range("B4:E50").ClearContents
  Sheet2.Range("B4").Value = CTName
  If k Then Sheet2.Range("C4").Resize(k, 3).Value = Res
End Sub

Private Sub CTyCon(k, ByVal CTy As String, ByVal Arr As Variant, ByVal TyLe#)
  Dim i&, r&, iK&, S, iKey$, CT$, Tl#
 
  For i = 1 To UBound(Arr)
    r = CLng(Arr(i))
    CT = sArr(r, 3)
    iKey = "#" & CT & "#"
    If Dic.exists(iKey) = False Then
      k = k + 1
      Res(k, 1) = CT
      Res(k, 2) = sArr(r, 4)
      Dic.Add iKey, k
    End If
    Tl = TyLe * Dic.Item(CTy & "|" & CT)
    iK = Dic.Item(iKey)
    Res(iK, 3) = Res(iK, 3) + Tl
    If Dic.exists(CT) Then Call CTyCon(k, CT, Split(Dic.Item(CT), "|"), Tl)
  Next i
End Sub
 

File đính kèm

Upvote 0
Giả sử D phát hành 1 tỷ đồng cổ phiếu, B mua 40% tức là 400 tr
...
B sở hữu gián tiếp E thông qua D, chỉ dùng để tính giá trị và chia cổ tức, không được quyền quản lý vì trong tay không có cổ phần....
1. Giá trị của công ty tính theo có trừ nợ. Không phải giá phát hành (giá giấy tờ lúc công ty đưa ra, khác với giá lưu hành là giá trên thị trường) cổ phiếu. Đương nhiên giá lưu hành của cổ phiếu cũng liên hệ với trị giá công ty, nhưng nó còn thêm bớt qua cách các nhà đầu tư đánh giá tương lai của công ty.
Nhóm tài chính dùng bảng báo cáo tài chính (financial report) làm công cụ chính, Balance Sheet để tính sở hữu cố đông, Profit and Loss để kiểm chứng hoạt động, và Cash Flow để xác định hoạt động tương lai.
Trường hợp công ty có nhiều cổ phân fowr công ty khác thì bảng báo cáo tài chính chung (consolidated) rất rắc rối. Hồi xưa tôi học suýt rớt môn này :p

2. Quyền quản lý còn tuỳ theo loại cổ phần. Điển hình Mark Zukerberg nắm cổ phần FB đâu có nhiều bằng các nhà băng. Nhưng hắn ta cũng nắm một số cổ phần xịn, chia lời thì có thể như nhau, nhưng có quyền bầu bán cao hơn các cổ phần khác.
 
Upvote 0
Trường hợp công ty có nhiều cổ phân fowr công ty khác thì bảng báo cáo tài chính chung (consolidated) rất rắc rối. Hồi xưa tôi học suýt rớt môn này :p
2. ... một số cổ phần xịn, chia lời thì có thể như nhau, nhưng có quyền bầu bán cao hơn các cổ phần khác.
Hồi tôi còn đi làm, phân tích lập trình cho BCTC chỉ dám làm hợp cộng, không dám làm hợp nhất. May là khách hàng cũng không đòi do họ cũng chưa lên sàn.
Cổ phiếu không xịn là cố phiếu phổ thông. Cổ phiếu xịn có nhiều loại, trong đó có cổ phiếu ưu đãi, cổ phiếu dành cho nhà sáng lập công ty, ... và tuỳ theo bản điều lệ công ty, chủ sở hữu sẽ có những đặc quyền như thế nào. Thậm chí có loại không được quyền sang nhượng.
_______
Phần giải thích cho bé bo là cho loại phổ thông
 
Upvote 0
Hồi tôi còn đi làm, phân tích lập trình cho BCTC chỉ dám làm hợp cộng, không dám làm hợp nhất. May là khách hàng cũng không đòi do họ cũng chưa lên sàn.
Cổ phiếu không xịn là cố phiếu phổ thông. Cổ phiếu xịn có nhiều loại, trong đó có cổ phiếu ưu đãi, cổ phiếu dành cho nhà sáng lập công ty, ... và tuỳ theo bản điều lệ công ty, chủ sở hữu sẽ có những đặc quyền như thế nào. Thậm chí có loại không được quyền sang nhượng.
_______
Phần giải thích cho bé bo là cho loại phổ thông
Cổ phiếu ưu đãi bạn nói trên có lẽ là prefrence shares. Chúng được chia lời trước cổ phiếu thông dụng (ordinary shares). Và nếu công ty giải toả hay phá sản thì chúng cũng được rút vốn trước cổ phiếu thông dụng. Loại cổ phiếu này thường không có quyền bầu bán.
Loại cổ phiếu này thích hợp cho những người chỉ muốn đầu tư kiếm lãi, gần như ký thác nhà băng (chỉ khác là vốn có thể tăng hay hao), không màng đến hoạt động công ty.
 
Upvote 0
Cổ phiếu ưu đãi bạn nói trên có lẽ là prefrence shares. Chúng được chia lời trước cổ phiếu thông dụng (ordinary shares). Và nếu công ty giải toả hay phá sản thì chúng cũng được rút vốn trước cổ phiếu thông dụng. Loại cổ phiếu này thường không có quyền bầu bán.
Loại cổ phiếu này thích hợp cho những người chỉ muốn đầu tư kiếm lãi, gần như ký thác nhà băng (chỉ khác là vốn có thể tăng hay hao), không màng đến hoạt động công ty.
Những đặc quyền hoặc hạn chế (không bầu bán) cho loại cổ phiếu cụ thể nào đều được ghi hết trong Bản điều lệ công ty, và do những thành viên sáng lập soạn thảo khi thành lập. Nếu sau đó có thay đổi điều lệ thì sẽ bị ràng buộc là không được thay đổi 1 vài điều khoản đặc quyền của nhà sáng lập. Cám ơn anh vì các thông tin bổ ích, chứ tôi chỉ học lý thuyết có năm bảy tiết trong 45 tiết môn "cổ phiếu trái phiếu", ngoài ra đọc truyện hoặc xem phim rồi hiểu thêm chẳng biết đúng hay sai.
 
Upvote 0
Theo bài 1 dữ liệu gốc là bảng 80x80 dòng, thì phải có bảng danh mục 80 dòng và cấu trúc bảng 80x80 phải như hình sau, các ô bị gạch chéo là các ô không có số liệu, nếu có tức là đang bị sở hữu vòng tròn. Ràng buộc thứ 2 của bảng này là tổng từng cột không vượt quá 100%, nên tôi sửa J5 từ 60% còn 50%

1608626427945.png

Sử dụng power query sẽ ra bảng data theo dòng để chạy code, và chỉ chạy trường hợp không sở hữu vòng tròn.

1608626488251.png

Code cũ nhưng có thể tính cùng lúc cho nhiều công ty.

1608626935764.png
 

File đính kèm

Upvote 0
Theo bài 1 dữ liệu gốc là bảng 80x80 dòng, thì phải có bảng danh mục 80 dòng và cấu trúc bảng 80x80 phải như hình sau, các ô bị gạch chéo là các ô không có số liệu, nếu có tức là đang bị sở hữu vòng tròn. Ràng buộc thứ 2 của bảng này là tổng từng cột không vượt quá 100%, nên tôi sửa J5 từ 60% còn 50%

View attachment 251643

Sử dụng power query sẽ ra bảng data theo dòng để chạy code, và chỉ chạy trường hợp không sở hữu vòng tròn.

View attachment 251644

Code cũ nhưng có thể tính cùng lúc cho nhiều công ty.

View attachment 251645
Theo mình code chạy trực tiếp trên dữ liệu gốc sẽ dể dùng hơn
 
Upvote 0
Theo mình code chạy trực tiếp trên dữ liệu gốc sẽ dể dùng hơn
Theo bài 1 thì dữ liệu gốc là bảng 80x80 đó anh. Do vụ sở hữu này ít biến động nên chỉ cần tạo query 1 lần, chỉ khi nào thay đổi tỷ lệ sở hữu mới phải refresh query
Chạy trực tiếp trên bảng 80x80 cũng được, nhưng một là tôi ghét dữ liệu không chuẩn, hai là chả biết có sắp xếp ngang dọc như nhau không, có bỏ sót còn 79x80 hay 80 x78 hay không.
 
Upvote 0
Theo bài 1 thì dữ liệu gốc là bảng 80x80 đó anh. Do vụ sở hữu này ít biến động nên chỉ cần tạo query 1 lần, chỉ khi nào thay đổi tỷ lệ sở hữu mới phải refresh query
Chạy trực tiếp trên bảng 80x80 cũng được, nhưng một là tôi ghét dữ liệu không chuẩn, hai là chả biết có sắp xếp ngang dọc như nhau không, có bỏ sót còn 79x80 hay 80 x78 hay không.
Nhìn bảng 80x80 dể hình dung mối quan hệ và kiểm soát được sở hữu vòng qua đường chéo
Máy tính mình và nhiều máy không chạy được power query
 
Upvote 0
Nhìn bảng 80x80 dể hình dung mối quan hệ và kiểm soát được sở hữu vòng qua đường chéo
Máy tính mình và nhiều máy không chạy được power query
Viết được nhưng cũng mất công thôi anh:
- Thêm 2 mảng 1 ngang 1 dọc: mảng dọc chứa công ty cha và mảng ngang chứa công ty con
- Thêm 1 cột dọc hoặc mảng dọc để biết công ty trong mảng dọc có con hay không (nhằm mục đích gán vào Dict). Công thức là Sum hàng ngang điều kiện >0 tức là có con
 
Lần chỉnh sửa cuối:
Upvote 0
Theo bài 1 dữ liệu gốc là bảng 80x80 dòng, thì phải có bảng danh mục 80 dòng và cấu trúc bảng 80x80 phải như hình sau, các ô bị gạch chéo là các ô không có số liệu, nếu có tức là đang bị sở hữu vòng tròn. Ràng buộc thứ 2 của bảng này là tổng từng cột không vượt quá 100%, nên tôi sửa J5 từ 60% còn 50%

View attachment 251643

Sử dụng power query sẽ ra bảng data theo dòng để chạy code, và chỉ chạy trường hợp không sở hữu vòng tròn.

View attachment 251644

Code cũ nhưng có thể tính cùng lúc cho nhiều công ty.

View attachment 251645
Không chắc, nhưng tôi nghĩ PQ vẫn có thể chạy được trường hợp này
 
Upvote 0
Không chắc, nhưng tôi nghĩ PQ vẫn có thể chạy được trường hợp này
Ý bạn nói trường hợp sở hữu vòng tròn? Thật ra có thuật toán là làm được, tại tôi không biết cách giải hợp lý (bên trên tôi có đưa ra 2 cách: đơn giản, và lặp đến khi 1 điều kiện nào đó đạt mức chấp nhận)
Còn trường hợp không vòng tròn thì PQ chỉ cần unpivot là xong (bài #32), hay là ý bạn dùng PQ cho đến kết quả cuối không cần VBA?
 
Upvote 0
Ý bạn nói trường hợp sở hữu vòng tròn? Thật ra có thuật toán là làm được, tại tôi không biết cách giải hợp lý (bên trên tôi có đưa ra 2 cách: đơn giản, và lặp đến khi 1 điều kiện nào đó đạt mức chấp nhận)
Còn trường hợp không vòng tròn thì PQ chỉ cần unpivot là xong (bài #32), hay là ý bạn dùng PQ cho đến kết quả cuối không cần VBA?
Vâng, tôi nghĩ dùng PQ có thể ra bảng cuối luôn, không cần thêm bước dùng Vba, tôi dùng ĐT nên không test được
 
Upvote 0
Viết được nhưng cũng mất công thôi anh:
- Thêm 2 mảng 1 ngang 1 dọc: mảng dọc chứa công ty cha và mảng ngang chứa công ty con
- Thêm 1 cột dọc hoặc mảng dọc để biết công ty trong mảng dọc có con hay không (nhằm mục đích gán vào Dict). Công thức là Sum hàng ngang điều kiện là >0 tức là có con
Chỉ cần mảng tỷ lệ cũng được
Mã:
Dim sArr(), aSoHuu(), aCT(), Res(), Dic As Object, CTm$, tenCTm$

Sub Main()
  Dim sRow&, sCol&, i&, j&, k&
 
  Set Dic = CreateObject("scripting.dictionary")
  aSoHuu = Sheet2.Range("A4:B" & Sheet2.Range("A65000").End(xlUp).Row).Value
  aCT = Sheet1.Range("P2", Sheet1.Range("Q65000").End(xlUp)).Value
  sArr = Sheet1.Range("G1:N7").Value
  sRow = UBound(sArr): sCol = UBound(sArr, 2)
  ReDim Res(1 To sRow * UBound(aSoHuu), 1 To 5)
  For i = 1 To UBound(aCT)
    Dic.Item("^" & aCT(i, 1) & "^") = aCT(i, 2)
  Next i
 
  For i = 2 To sRow
    CTm = sArr(i, 1)
    For j = 2 To sCol
      If Len(sArr(i, j)) > 0 Then
        Dic.Item(CTm) = Dic.Item(CTm) & "|" & sArr(1, j)
        Dic.Item(CTm & "|" & sArr(1, j)) = sArr(i, j)
      End If
    Next j
  Next
  For i = 1 To UBound(aSoHuu)
    CTm = aSoHuu(i, 1)
    tenCTm = Dic.Item("^" & CTm & "^")
    If Dic.exists(CTm) Then Call CTyCon2(k, CTm, Split(Dic.Item(CTm), "|"), 1)
  Next i
  Sheet2.Range("D4:H500").ClearContents
  If k Then Sheet2.Range("D4").Resize(k, 5).Value = Res
End Sub

Private Sub CTyCon2(k, ByVal CTy As String, ByVal Arr As Variant, ByVal TyLe#)
  Dim i&, iK&, iKey$, CT$, Tl#
 
  For i = 1 To UBound(Arr)
    CT = Arr(i)
    iKey = CTm & "#" & CT
    If Dic.exists(iKey) = False Then
      k = k + 1
      Dic.Add iKey, k
      Res(k, 1) = CTm
      Res(k, 2) = tenCTm
      Res(k, 3) = CT
      Res(k, 4) = Dic.Item("^" & CT & "^")
    End If
    Tl = TyLe * Dic.Item(CTy & "|" & CT)
    iK = Dic.Item(iKey)
    Res(iK, 5) = Res(iK, 5) + Tl
    If Dic.exists(CT) Then Call CTyCon2(k, CT, Split(Dic.Item(CT), "|"), Tl)
  Next i
End Sub
 

File đính kèm

Upvote 0
Theo bài 1 dữ liệu gốc là bảng 80x80 dòng, thì phải có bảng danh mục 80 dòng và cấu trúc bảng 80x80 phải như hình sau, các ô bị gạch chéo là các ô không có số liệu, nếu có tức là đang bị sở hữu vòng tròn. Ràng buộc thứ 2 của bảng này là tổng từng cột không vượt quá 100%, nên tôi sửa J5 từ 60% còn 50%

View attachment 251643

Sử dụng power query sẽ ra bảng data theo dòng để chạy code, và chỉ chạy trường hợp không sở hữu vòng tròn.

View attachment 251644

Code cũ nhưng có thể tính cùng lúc cho nhiều công ty.

View attachment 251645
Dùng PQ sử dụng các chức năng merge Inner và Left Anti, tôi lấy data của bạn nhưng kết quả một số không khớp ví dụ như A sở hữu E chỉ có 10%, file bạn tính ra 13.5%, tôi tính tay cũng chỉ có 10%
 

File đính kèm

Upvote 0
Dùng PQ sử dụng các chức năng merge Inner và Left Anti, tôi lấy data của bạn nhưng kết quả một số không khớp ví dụ như A sở hữu E chỉ có 10%, file bạn tính ra 13.5%, tôi tính tay cũng chỉ có 10%
Minh hoạ A sở hữu E 13.5%: E chỉ có 2 cha là C và D, A chỉ sở hữu B và C, B lại sở hữu D. Thông qua B và C tính ra 3 con số cộng lại: ABCE, ABDE và ACE

1608709818351.png
 
Upvote 0

File đính kèm

Upvote 0
Theo mình code chạy trực tiếp trên dữ liệu gốc sẽ dể dùng hơn
Chạy trên bảng 80x80
- Thêm 2 mảng 1 ngang 1 dọc: mảng dọc chứa công ty cha và mảng ngang chứa công ty con
- Thêm 1 cột dọc hoặc mảng dọc để biết công ty trong mảng dọc có con hay không (nhằm mục đích gán vào Dict). Công thức là Sum hàng ngang điều kiện >0 tức là có con
Thấy file và code anh @HieuCD mà ngợp quá, cố viết theo mà không được, thôi thì viết đơn giản như trên: Không thêm 2 mảng 1 ngang 1 dọc chứa công ty cha và công ty con, nhưng có thêm 1 cột phụ cho biết 1 công ty có là công ty cha hay không (có sở hữu công ty con nào hay không). Đồng thời tăng dữ liệu lên 42 x 42 công ty. Ma trận dữ liệu không cần đầy đủ dòng cột và không cần thứ tự.

1608913826884.png

Code anh @HieuCD có bao nhiêu chạy hết, nhưng code này muốn chạy bao nhiêu cũng được, chạy hết cũng được, muốn chạy công ty nào thì điền vào cột A không cần theo thứ tự

1608914053939.png

1608943082643.png
 

File đính kèm

Lần chỉnh sửa cuối:
Upvote 0
Bổ sung: có thể bỏ cột phụ D, thay đoạn code
PHP:
    For i = 2 To UBound(SArr, 1)
        If IsParent(i, 1) Then
            ikey = SArr(i, 1)
            Dict1.Item(ikey) = i
        End If
    Next
Bằng
PHP:
    For i = 2 To UBound(SArr, 1)
        For j = 2 To UBound(SArr, 2)
            If SArr(i, j) > 0 Then
                ikey = SArr(i, 1)
                Dict1.Item(ikey) = i
                Exit For
            End If
        Next
    Next
 
Upvote 0

Bài viết mới nhất

Back
Top Bottom