CÔNG TY CỔ PHẦN BLUESOFTS

CÔNG TY CỔ PHẦN BLUESOFTS

Chia sẻ file Excel có VBA qua mạng với A-Tools P2 - Mở sheet trong máy chủ

Tự viết code kết nối máy chủ, mở sheet, range và ngắt kết nối. Cách làm này giúp bạn chủ động làm việc với sheet trong máy chủ mà không dùng menu A-Tools.
Khi bạn lập trình VBA mở một sheet nào đó nhưng nếu sheet trong file chia sẻ từ máy chủ A-Tools thì sẽ gặp lỗi. Các lệnh dưới đây sẽ gặp lỗi
Sheets("Tên sheet").Select
Sheetx.Select

Lỗi là do các sheet này có thể chưa được mở từ máy chủ, điều này khác với file Excel không chia sẻ mạng. Bài hướng dẫn này tôi hướng dẫn cách các bạn mở sheet từ máy chủ sau đó bạn có thể thực hiện các lệnh Excel thông thường mà không gặp lỗi.

Video hướng dẫn chi tiết



 
Màn hình "Client manager"/"Quản trị máy khách" của A-Tools hiển thị danh sách tên các file và các sheet, range như dưới đây



Mã nguồn VBA lập trình sẽ là

'Client-site
Sub ListAllUserRanges() 
   Dim xnet As New BSNetwork 
   Dim db As BSDatabase  'Get workbook
   Dim ur As BSUserRange  'Get sheet/range
   If Not xnet.Connected Then 
      xnet.Connect 
   End If 
   If Not xnet.Connected Then Exit Sub 
   'List of files in server
   For Each db In xnet.Databases 
      Debug.Print "Database: " & db.Name 
      db.UserRanges.Update 
      'List of sheet/range = BSUserrange in database
      For Each ur In db.UserRanges 
         Debug.Print vbTab & "Userrange: " & ur.Name 
      Next 
   Next 
   Set xnet = Nothing 
End Sub 

(Lệnh Debug.Print in nội dung bất kỳ ra màn hình "Immediate". Nếu bạn không nhìn thấy cửa sổ này hãy nhấn CTRL+G, hoặc vào menu View -> Immediate".)


Để bạn thực hiện việc lập trình VBA với menu A-Tools hãy làm từng bước như sau

1. Nhúng thư viện lập trình vào VBAProject
+ Vào môi trường lập trình VBA - nhấn ALT+F11
+ Chọn VBAProject của file Excel bạn muốn viết code
+ Vào menu Tools->References... check mục mà có từ "Add-in A-Tools..." thuộc thư viện "addinatools.dll"

2. Vào menu Insert->Module (nếu cần tạo module mới, bạn có thể viết vào module, class, userform đã có).

Copy mã nguồn VBA dưới đây.
'Client-site: kết nối máy chủ, mở sheet
Sub OpenSheetOrRangeFromServer() 
   Dim xnet As New BSNetwork 
   Dim db As BSDatabase  'Get workbook
   Dim ur As BSUserRange  'Get sheet/range
   If Not xnet.Connected Then 
      xnet.Connect 
   End If 
   If Not xnet.Connected Then Exit Sub 
   'MsgBox "Connected!", vbInformation
   'List of files in server
   'For Each db In xnet.Databases
   ' Debug.Print db.Name
   'Next
   'List of sheet/range = BSUserrange in file "Shops.xls"
   Set db = xnet.Databases("Shops.xls") 
   db.UserRanges.Update 
   'Debug.Print "File: Shops.xls"
   'For Each ur In db.UserRanges
   ' Debug.Print ur.Name
   'Next
   'Open range "Shop 1_A9-F30"
   If Not db.UserRanges.IsOpened("Shop 1_A9-F30") Then 
      Set ur = db.UserRanges.Open("Shop 1_A9-F30") 
   Else 
      Set ur = db.UserRanges("Shop 1_A9-F30") 
   End If 
   'Write data into sheet
   Dim sh As Worksheet 
   Set sh = ur.Sheet 
   sh.Range("B15").Value = "HH002" 
   Set xnet = Nothing 
End Sub 

Sub CloseSheetOrRange() 'Đóng vùng
   Dim xnet As New BSNetwork 
   Dim db As BSDatabase 
   If xnet.IsRunning And Not xnet.IsServer Then  'Client is running?
      Set db = xnet.Databases("Shops.xls") 
      'Open range "Shop 1_A9-F30"
      If db.UserRanges.IsOpened("Shop 1_A9-F30") Then 
         db.UserRanges("Shop 1_A9-F30").Close False 
      End If 
   End If 
   Set xnet = Nothing 
End Sub 

Sub Disconnect() 'Ngắt kết nối
   Dim xnet As New BSNetwork 
   If xnet.IsRunning And Not xnet.IsServer Then  'Client is running?
      xnet.Disconnect 
   End If 
   Set xnet = Nothing 
End Sub 

Kiến thức mở rộng

Tình huống bạn đã mở sheet có phân vùng ảo - Vùng tạo trong máy chủ từ một sheet gõ, nó có tên khác với tên sheet gốc, phân vùng ảo này cho phép ẩn cột ẩn dòng và các đặc tính khác giúp cho các nhóm user có các quyền trên một sheet khác nhau. Vì tên sheet sẽ bị thay đổi ở phía máy khách cho nên khi bạn lập trình VBA gọi đích danh một tên sheet cụ thể sẽ bị lỗi, vì tên sheet được đổi khi mở sheet ảo. Để xử lý tính huống này bạn xem code tôi viết dưới đây.


Giả thiết vùng chia sẻ từ máy chủ có tên "Shop 1_A9-F30" được tạo từ sheet "Shop 1". Phía máy khách khi mở vùng này thì tên sheet có tên là "Shop 1_A9-F30". Cách để bạn nhận điều khiển sheet của phân vùng ảo dựa theo tên sheet góc ( là "Shop 1" ) như sau.

Sub TestGetSheetFromClient() 
   Dim sh As Worksheet 
   Set sh = GetSheetOpened("Shops.xls", "Shop 1") 
   If Not sh Is Nothing Then 
      sh.Select 
   End If 
End Sub 
 
Hàm GetSheetOpened() tôi viết để trả về điều khiển sheet theo tên workbook và tên sheet gốc bạn đưa vào. Mã nguồn hàm này viết như sau.

Function GetSheetOpened(ByVal wbName As String, ByVal shName As String) As Object 
   Dim xnet As New BSNetwork  'Connect to server
   Dim db As BSDatabase  'Workbook
   Dim ur As BSUserRange 
   Dim sh As Worksheet 
   Set GetSheetOpened = Nothing 
   If Not xnet.IsRunning Or xnet.IsServer Then 
      Set GetSheetOpened = Workbooks(wbName).Sheets(shName) 
      GoTo lbEndFunc 
   End If 
   Set db = xnet.Databases(wbName) 
   db.UserRanges.Update 
   'List all sheet and range in "Shops.xls"
   For Each ur In db.UserRanges 
      'Debug.Print ur.Name
      If StrComp(ur.Name, shName, vbTextCompare) = 0 Or StrComp(ur.RemoteWorksheet, shName, vbTextCompare) = 0 Then 
         Set sh = ur.Sheet 
         If sh.Visible = xlSheetVisible Then 
            Set GetSheetOpened = sh 
            Exit For 
         End If 
      End If 
   Next 
lbEndFunc: 
   Set xnet = Nothing 
End Function 

Nếu bạn đang có file Excel có VBA thì bài hướng dẫn này rất quan trọng để bạn sửa lại. Nếu bạn chưa học Hay muốn học lập trình VBA từ Bluesofts thì đăng ký khóa học VBA tại đay: "Lập trình VBA cơ bản".
 
Các câu hỏi cần hỗ trợ các bạn có thể đăng trong group Facebook: https://www.facebook.com/groups/hocexcel

BÀI HỌC LIÊN QUAN