Lập trình Client/Server với NetForVAT – Caro Game (1 người xem)

Liên hệ QC

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

thuanfun

Thành viên chính thức
Tham gia
7/2/09
Bài viết
83
Được thích
94
Giới tính
Nam
NetForVBA là thư viện .NET miễn phí các tính năng cơ bản (Freemium) cung cấp cho VBA những tính năng mạnh mẽ từ Microsoft .NET Framework. Bạn vui lòng tải hoặc nâng cấp lên bản mới nhất tại đây để luôn là phiên bản mới nhất.

Tôi xin giới thiệu một tính năng miễn phí mới của NetForVBA là lập trình kết nối qua mạng LAN.

demo-caro.png


Để kết nối giữa Client và Server qua mạng LAN, NetForVBA cung cấp 2 class là dnSocketLANServer dành cho phía server và dnSocketLANClient dành cho phía máy client.

Server

Để khởi tạo Server, bạn cần khai báo biến dnSocketLANServer, gắn Port, đăng ký events và chạy thủ tục Start.

Mã:
Dim server As New dnSocketLANServer

'# Gắn Port
server.port = 1234

'# Đăng ký Event sẽ gọi ở hàm VBA nào
server.regEvent_OnClientConnected ThisWorkbook, "server_OnClientConnected"
server.regEvent_OnMessage ThisWorkbook, "server_OnMessage"
server.regEvent_OnClientDisconnected ThisWorkbook, "server_OnClientDisconnected"

'# chạy nào!
server.Start

Ở code trên có 3 event cơ bản là OnClientConnected, OnMessage, OnClientDisconnected tương ứng với các sự kiện của client là: kết nối, gửi tin đến, ngừng kết nối. 3 sự kiện này lần lượt được đăng ký đến 3 Sub VBA là:

Mã:
Sub server_OnClientConnected(sender As Object, e As dnSocketLANClientEventArgs)
   'Sự kiện xảy ra khi có một Client mới kết nối thành công đến Server
End Sub

Sub server_OnMessage(sender As Object, e As dnSocketLANMessageEventArgs)
   'Sự kiện xảy ra khi nhận được tin (message) từ client gửi đến Server
End Sub

Sub server_OnClientDisconnected(client As dnSocketLANClient, e As dnEventArgs)
   'Sự kiện xảy ra khi có một Client ngừng kết nối (lỗi, mất mạng hoặc tự thoát)
End Sub

Để gửi một message đến client ta dùng hàm:

Mã:
'# gửi String
server.SendString "địa chỉ IP của client", "dòng unicode text muốn gửi"

'# gửi mảng byte
server.SendBytes "địa chỉ IP của client", byteArray, "ghi chú của bạn"

Client

Để client kết nối với Server, bạn cần khai báo biến dnSocketLANClient, đăng ký events và chạy thủ tục Connect “IP của máy server”, port.

Mã:
Dim client As New dnSocketLANClient

'# Đăng ký Event sẽ gọi ở hàm VBA nào
client.regEvent_OnConnected ThisWorkbook, "client_OnConnected"
client.regEvent_OnMessage ThisWorkbook, "client_OnMessage"
client.regEvent_OnDisconnected ThisWorkbook, "client_OnDisconnected"

'# kết nối nào! (nhớ thay IP và Port của bạn)
client.Connect "192.168.1.1", 1234

Các sự kiện được gọi ở 3 Sub cơ bản:

Mã:
Sub client_OnConnected(sender As dnSocketLANClient, e As Object)
   'Xảy ra khi kết nối thành công
End Sub

Sub client_OnMessage(sender As Object, e As dnSocketLANMessageEventArgs)
   'Xảy ra khi nhận được message từ sender (có thể là server hoặc client khác)
End Sub

Sub client_OnDisconnected(sender As dnSocketLANClient, e As Object)
'Xảy ra khi ngừng kết nối
End Sub

Client gửi tin đến server hoặc client khác bằng các hàm sau:

Mã:
'# gửi String đển Server
client.SendString "dòng unicode text muốn gửi đến Server"

'# gửi mảng byte đến Server
client.SendBytes byteArray, "ghi chú của bạn"

'# gửi mảng byte đến Client khác
client.SendToIP "IP của client bạn muốn gửi đến", byteArray, "ghi chú của bạn"

Dưới đây là file ví dụ về Game Caro qua mạng LAN:

PS: Tính năng lập Client/Server này em mới làm nên còn một số lỗi, em mong các bác góp ý phía dưới để em chỉnh sửa để có một giải pháp kết nối Client/Serser miễn phí hoàn thiện nhất dùng cho VBA.
 
Lần chỉnh sửa cuối:
Cái truyền qua truyền lại thì mình biết, chỉ không biết làm sao mà từ client open file excel tren sever thôi???
 
Upvote 0
Mạnh cũng biết chút chút rồi trên VBA ai biết API thì viết tốt có điều nó ko hổ trợ tốt như vb6.delphi , vb.net.....còn cái taskpane nửa Mạnh chưa thấy người thứ 3 viết .ocx đang hóng tiếp
 
Upvote 0
Mạnh cũng biết chút chút rồi trên VBA ai biết API thì viết tốt có điều nó ko hổ trợ tốt như vb6.delphi , vb.net.....

Viết được API+VBA thì sẽ triển khai nhàn hơn bác nhỉ? ko phải cõng thêm Lib nữa, giảm được các lỗi không mong muốn từ bên ngoài
 
Upvote 0
Viết được API+VBA thì sẽ triển khai nhàn hơn bác nhỉ? ko phải cõng thêm Lib nữa, giảm được các lỗi không mong muốn từ bên ngoài
API trên VBA trên google có hết tại ít ai quan tâm hay mò nó ...Mạnh copy xài thế thôi
 
Upvote 0
Mở Tren may client (flie do nam tren sever)

Cài này phải xem ngữ cảnh thế nào?
#1: một mình làm việc cả file: thì tốt nhất tải cả file về rồi khi xong việc lại up lên (dung code auto)
#2: một mình làm việc với 1 sheet/range (không đụng độ với ai): tải các thông tin range đó về hiển thị trên client, lúc nào cần xong thì gửi lên (real-time hoặc lâu lâu up phát đỡ mệt)
#3: làm chung với người khác (cái này đụng nhau rồi): cái này em nghĩ cần xây dựng message queue để xếp hàng các lệnh mà client gửi lên, rồi xử lý lần lượt sẽ tránh được đụng độ

Em nghĩ vậy không biết có ý nào giống bác không?
 
Upvote 0
Cài này phải xem ngữ cảnh thế nào?

#2: một mình làm việc với 1 sheet/range (không đụng độ với ai): tải các thông tin range đó về hiển thị trên client, lúc nào cần xong thì gửi lên (real-time hoặc lâu lâu up phát đỡ mệt)
Cái mục này mình thấy hợp lý. Tuy nhiên Rang đó chứa công thức có tham chiếu đến File hay Sheet khác mà tải các thông tin range đó về hiển thị trên client sao được nhỉ
 
Upvote 0
Mình thì
Cái mục này mình thấy hợp lý. Tuy nhiên Rang đó chứa công thức có tham chiếu đến File hay Sheet khác mà tải các thông tin range đó về hiển thị trên client so được nhỉ

Cái này em nghĩ không nên suy nghĩ kiểu clone 100% thông tin của range máy chủ về đặt vào client, mà chỉ nên lấy những thông tin cần thiết.

Nền tảng cơ bản vẫn là truyền message giữa 2 bên, và người viết code làm chủ được việc 2 bên gửi cho nhau những thông tin gì. Với Cell ta có thể chỉ lấy Value và thông tin Format (Font, Color, Border, ...)

Ví dụ ta có thể giới hạn ở Client, những Cell có công thức là ReadOnly và chỉ hiện Value (còn công thức thì hiện chỗ khác như comment, tooltip, ...), những Cell không có công thức thì cho nhập. Nhập xong đẩy lên Server, Server tính toán xong đẩy lại cho client giá trị của các Cell để hiển thị kết quả tính toán.
 
Upvote 0
Ví dụ ta có thể giới hạn ở Client, những Cell có công thức là ReadOnly và chỉ hiện Value (còn công thức thì hiện chỗ khác như comment, tooltip, ...), những Cell không có công thức thì cho nhập. Nhập xong đẩy lên Server, Server tính toán xong đẩy lại cho client giá trị của các Cell để hiển thị kết quả tính toán.
Cái này không hay, có luôn công thức mới hay chứ chỗ này mình B I BI sắc BÍ :giveup:
 
Upvote 0
Hihihi giải quyết được vấn đề này trước những cái khác tính sau. Hihi
 
Upvote 0
Hihihi giải quyết được vấn đề này trước những cái khác tính sau. Hihi

Theo mình thì thế này:
#1: Convert Range thành String (tạm gọi là RangeString gồm value và các format màu sắc, font, border, ...)
#2: gửi sang máy kia
#3: Khi nhận được RangeString, convert nó thành các thuộc tính của Range rồi gán các thuộc tính đó cho một Range khác ở Client

Ở sự liện Worksheet_Change ta sẽ kiểm tra Target xem có nằm trong Range đang chia sẻ không, nếu nằm trong thì làm như các bước trên
 
Upvote 0
Mình cũng từng nghĩ tới rồi tuy nhiên khi gán excel báo cập nhật công thức sao. Thực ra thì giống như copy.

Mà công nhận bạn nhìn ra vấn đề mình hỏi nhanh thật.
Hihi hy vọng là sẽ đi đúng hướng....
 
Lần chỉnh sửa cuối:
Upvote 0
Mình cũng từng nghĩ tới rồi tuy nhiên khi gán excel báo cập nhật công thức sao. Thực ra thì giống như copy.

Mà công nhận bạn nhìn ra vấn đề mình hỏi nhanh thật

#1: Server mới tính toán công thức. Client chỉ hiển thị kết quả và nhập value (ở các ô không có công thức => không làm thay đổi không thức)
#2: Value mới nhận ở client được đẩy lên server, server gán value đó vào cell tương ứng (tất nhiên cũng không có công thức)
#3: Server tự động tính toán dựa vào các công thức trong cell => phát ra sự kiện Change
#4: Server có sự kiện change: lấy tất cả các cell thay đổi (để giảm dung lượng) ném lại cho client hiển thị

Vậy có được không bác?
 
Upvote 0
Mình muốn client vẫn có công thức của sever mà không tính toán được không

Cái này trên Excel thì mình chưa biết cách :D
Có thể sử dụng API để hiển thị thành công thức (FormulaBar) giả :D để hiển thị công thức giả (không có trong cell mà lấy ở chỗ khác)
 
Upvote 0
Cái này trên Excel thì mình chưa biết cách :D
Có thể sử dụng API để hiển thị thành công thức (FormulaBar) giả :D để hiển thị công thức giả (không có trong cell mà lấy ở chỗ khác)
Không bạn hiểu nhầm ý mình rồi. Ý mình là nguyên 1 vung của sever khi chuyển qua client thì khi client chọn vào o đó mà o đó nếu có công thức thì client vẫn nhìn thấy công thức
 
Upvote 0
Không bạn hiểu nhầm ý mình rồi. Ý mình là nguyên 1 vung của sever khi chuyển qua client thì khi client chọn vào o đó mà o đó nếu có công thức thì client vẫn nhìn thấy công thức

Có 2 trường hợp khi xem công thức ở cell:
#1: chọn bình thường (không editing): chỉ nhìn thấy công thức ở FormulaBar
#2: click đúp (F2) vào cell: thấy công thức ở FormulaBar và ở editing cell

Với công thức ở FormulaBar: dùng API (SetParent, MoveWindow, ...) để tạo nội dung giả cho FormulaBar
Với công thức ở editing cell: chèn vào đó một TextBox ở chế độ ReadOnly giả editing cell
 
Upvote 0
Có 2 trường hợp khi xem công thức ở cell:
#1: chọn bình thường (không editing): chỉ nhìn thấy công thức ở FormulaBar
#2: click đúp (F2) vào cell: thấy công thức ở FormulaBar và ở editing cell

Với công thức ở FormulaBar: dùng API (SetParent, MoveWindow, ...) để tạo nội dung giả cho FormulaBar
Với công thức ở editing cell: chèn vào đó một TextBox ở chế độ ReadOnly giả editing cell
Cách này không ổn.
Có cách nào minh Share File excel qua client sever không ?
 
Upvote 0
Upvote 0
Upvote 0
Để kết nối giữa Client và Server qua mạng LAN, NetForVBA cung cấp 2 class là dnSocketLANServer dành cho phía server và dnSocketLANClient dành cho phía máy client.

Bạn cho hỏi thêm chút.
Lúc trước cũng mày mò vụ dùng Windows socket trong VBA nhưng thấy bị một hạn chế là ứng với mỗi Client thì phải tạo 1 Winsock control ở phía Server để nhận tin.
- Theo tôi được biết thì trong .NET có thể dùng mảng các Winsock control, không biết trong cái class trên của bạn cũng dùng mảng Control luôn không? để có thể dùng cho nhiều Client mà không cần mỗi client lại chèn một winsock control.
- Cái class này có thể gửi gói tin là một object luôn không hay buộc phải chuyển sang XML? ví dụ: gửi cái ADO recordset
Kiến thức vụ này tôi không nhiều vì cũng chưa có nhu cầu thiết kế cái ứng dụng nào phải dùng Socket :) , bạn hướng dẫn để hiểu thêm nhé.
 
Upvote 0
Bạn cho hỏi thêm chút.
Lúc trước cũng mày mò vụ dùng Windows socket trong VBA nhưng thấy bị một hạn chế là ứng với mỗi Client thì phải tạo 1 Winsock control ở phía Server để nhận tin.
- Theo tôi được biết thì trong .NET có thể dùng mảng các Winsock control, không biết trong cái class trên của bạn cũng dùng mảng Control luôn không? để có thể dùng cho nhiều Client mà không cần mỗi client lại chèn một winsock control.
- Cái class này có thể gửi gói tin là một object luôn không hay buộc phải chuyển sang XML? ví dụ: gửi cái ADO recordset
Kiến thức vụ này tôi không nhiều vì cũng chưa có nhu cầu thiết kế cái ứng dụng nào phải dùng Socket :) , bạn hướng dẫn để hiểu thêm nhé.
Mạnh cũng đang mò cái này mà khúc biết khúc không ... cũng mong có nhiều thành viên tham gia giao lưu
Tham khảo bài 700 này xem sao ... code đó nó tìm kiếm và lấy dữ liệu từ Server về
 
Upvote 0
Lang thang copy được cái Code VB6 Server mà nó xài Winsock control úp cho ai cần tham khảo thêm

Qua tuần rảnh Mạnh mới chuyển nó qua xài API xem tình hình sao

Theo như trong File .txt nó nói kết nối 200 máy chạy ok ... Mạnh mới thử 5 máy thì thấy ok
điều chỉnh số máy kết nối khi Form_Load ... tuỳ chỉnh theo ý đồ ai đó viết lại code ... còn mạnh Úp nguyên mẫu code gốc của người ta
Mã:
Private Sub Form_Load()
    ' Use which host/ports?
    InitServer "127.0.0.1", "1000,2000,3000,4000"
End Sub
 

File đính kèm

Upvote 0
Bạn cho hỏi thêm chút.
Lúc trước cũng mày mò vụ dùng Windows socket trong VBA nhưng thấy bị một hạn chế là ứng với mỗi Client thì phải tạo 1 Winsock control ở phía Server để nhận tin.
- Theo tôi được biết thì trong .NET có thể dùng mảng các Winsock control, không biết trong cái class trên của bạn cũng dùng mảng Control luôn không? để có thể dùng cho nhiều Client mà không cần mỗi client lại chèn một winsock control.
- Cái class này có thể gửi gói tin là một object luôn không hay buộc phải chuyển sang XML? ví dụ: gửi cái ADO recordset
Kiến thức vụ này tôi không nhiều vì cũng chưa có nhu cầu thiết kế cái ứng dụng nào phải dùng Socket :) , bạn hướng dẫn để hiểu thêm nhé.
Em thì chuyển từ recorset sang xml rồi chuyển sang client dua vào lại recorset
 
Upvote 0
Bạn cho hỏi thêm chút.
Lúc trước cũng mày mò vụ dùng Windows socket trong VBA nhưng thấy bị một hạn chế là ứng với mỗi Client thì phải tạo 1 Winsock control ở phía Server để nhận tin.
- Theo tôi được biết thì trong .NET có thể dùng mảng các Winsock control, không biết trong cái class trên của bạn cũng dùng mảng Control luôn không? để có thể dùng cho nhiều Client mà không cần mỗi client lại chèn một winsock control.
- Cái class này có thể gửi gói tin là một object luôn không hay buộc phải chuyển sang XML? ví dụ: gửi cái ADO recordset
Kiến thức vụ này tôi không nhiều vì cũng chưa có nhu cầu thiết kế cái ứng dụng nào phải dùng Socket :) , bạn hướng dẫn để hiểu thêm nhé.

Chào bạn ongke0711,

Trong .NET thì các thành phần Socket không phải control (trên Form) nữa mà là class.

Trong NetForVBA tôi dùng như sau:

Phía Server:
1. Dùng TcpListener để nghe xem có client nào mới kết nối không, nếu có thì chuyển sang 2
2. Dùng TcpClient để lưu trữ thông tin kết nối của client vào mảng.

Phía Client:
Dùng TcpClient để lưu trữ thông tin kết nối

Về định dạng gói tin, các gói tin cơ bản đều là kiểu mảng Byte. Các kiểu String hay Object đều chuyển sang mảng Byte rồi mới truyền đi.

NetForVBA hiện nay đang hỗ trợ 2 kiểu String và mảng Byte. Tuy nhiên bạn có thể chuyển một dnDictionary sang bằng cách dùng Json (app.Json.**) để convert qua lại giữa String và dnDictionary. Để convert Scripting.Dictionary hay dùng trong VBA sang dnDictionary bạn dùng hàm FromScriptingDictionary.
 
Upvote 0
Lang thang copy được cái Code VB6 Server mà nó xài Winsock control úp cho ai cần tham khảo thêm

Qua tuần rảnh Mạnh mới chuyển nó qua xài API xem tình hình sao

Theo như trong File .txt nó nói kết nối 200 máy chạy ok ... Mạnh mới thử 5 máy thì thấy ok
điều chỉnh số máy kết nối khi Form_Load ... tuỳ chỉnh theo ý đồ ai đó viết lại code ... còn mạnh Úp nguyên mẫu code gốc của người ta

:) Trong bài viết lúc trước (link bài #6) tôi cũng có demo kết nối dùng Winsock trong Excel kết nối tới CSDL Access nhưng như đã đề cập là Winsock trong VBA không hỗ trợ mảng nên khi viết code 1 winsock control chỉ đại diện cho 1 kết nối chứ không khai báo một mảng các Client như trong VB.
Do đó demo của bạn là VB6 thì nó kết nối nhiều client là đúng rồi. VBA thì tôi không khai báo được mảng các Client, hay do tôi code chưa đúng nhỉ??? Ở phía Server tôi phải dùng 5 cái winsock control để nhận 5 cái kết nối từ Client thay vì 1 cái WS control với index: Winsock(0), Winsock(1), ...

Screen Shot 2019-12-22 at 2.45.14 PM.png
 
Upvote 0
:) Trong bài viết lúc trước (link bài #6) tôi cũng có demo kết nối dùng Winsock trong Excel kết nối tới CSDL Access nhưng như đã đề cập là Winsock trong VBA không hỗ trợ mảng nên khi viết code 1 winsock control chỉ đại diện cho 1 kết nối chứ không khai báo một mảng các Client như trong VB.
Do đó demo của bạn là VB6 thì nó kết nối nhiều client là đúng rồi. VBA thì tôi không khai báo được mảng các Client, hay do tôi code chưa đúng nhỉ??? Ở phía Server tôi phải dùng 5 cái winsock control để nhận 5 cái kết nối từ Client thay vì 1 cái WS control với index: Winsock(0), Winsock(1), ...

View attachment 230320
Nếu Bạn rảnh cứ nghiên cứu trước đi ... cuối năm Mạnh đang kẹt khoãng 1 tuần chi đó ... lúc rảnh vào GPE à ơi tẹo
Xong công việc Mạnh mới coi chi tiết sao có chi sẻ cùng các Bạn chơi tiếp

Tại vì như cầu công việc của Mạnh hướng tới tự viết cái Server xài Database.accdb cho các máy kết nối trong LAN nên sẻ theo đuổi nó đấy
Nó cũng cứ loanh quanh cái GetData ............. SendData

Có vậy thôi mà nhức đầu ghê :p

Úp tiếp cho Ai cần code sau ....Tham khảo thêm của thiên hạ mà có chi mà cất làm của riêng ... cho đi để nhận lại nhiều hơn he
Nó xài Database.mdb đấy ... dù là VB6 đồ cổ nhưng vẫn ứng dụng tốt
 

File đính kèm

Upvote 0
Chán sư phụ lắm toàn có chơi 1 mình ... có chi dấu như mèo dấu *** :p ;)
Làm gì mà phải dấu.
Em bỏ thời gian, tiền bạc, chất xám ra tìm đọc tài liệu suy nghĩ đạt được chút thành quả, theo anh có ai lại bê nguyên cái thành quả đó đi cho người khác, trong khi ai đó không bỏ gì hết (ngồi mát ăn bát vàng à).
Anh cũng đã kiếm nát trên mạng rồi có ai chia sẻ hong.
Anh muốn đạt được mục đích thì phải đầu tư chứ, làm đi vướng chỗ nào các anh trên đây hỗ chợ chứ ngồi đó mà xin nguyên cục Code ai cho.
(hồi xưa em mới vô diễn đàn cũng có biết gì đâu, cũng nhắn tin hỏi người này người kia, có người thì hồi âm, cũng có người không hồi âm. riết rồi em nghĩ thay vì đợi người thì mình tự mò hay hơn).
Còn muốn lẹ nữa anh thuê Team viết chuyển giao Soure cho anh hihi
 
Upvote 0
Bạn kieumanh luôn có cách dùng từ rất lạ...:)
 
Upvote 0
Làm gì mà phải dấu.
Em bỏ thời gian, tiền bạc, chất xám ra tìm đọc tài liệu suy nghĩ đạt được chút thành quả, theo anh có ai lại bê nguyên cái thành quả đó đi cho người khác, trong khi ai đó không bỏ gì hết (ngồi mát ăn bát vàng à).
Anh cũng đã kiếm nát trên mạng rồi có ai chia sẻ hong.
Anh muốn đạt được mục đích thì phải đầu tư chứ, làm đi vướng chỗ nào các anh trên đây hỗ chợ chứ ngồi đó mà xin nguyên cục Code ai cho.
(hồi xưa em mới vô diễn đàn cũng có biết gì đâu, cũng nhắn tin hỏi người này người kia, có người thì hồi âm, cũng có người không hồi âm. riết rồi em nghĩ thay vì đợi người thì mình tự mò hay hơn).
Còn muốn lẹ nữa anh thuê Team viết chuyển giao Soure cho anh hihi
Mạnh Sorry he mà Sài gòn gần Bình dương lắm ... khi nào Rảnh Mời Sư phụ cùng Sư phụ RE kia qua Bình dương chơi nha có chi A lô Mạnh
 
Upvote 0
Mạnh Sorry he mà Sài gòn gần Bình dương lắm ... khi nào Rảnh Mời Sư phụ cùng Sư phụ RE kia qua Bình dương chơi nha có chi A lô Mạnh
Thôi. cám ơn anh em ở quê chứ không phải sài phố.
em gần đạt đến cảnh giới rồi nên em hỏng quan tâm :giveup:
 
Upvote 0

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

Back
Top Bottom