Tạo link table bằng VB

Thảo luận trong 'Ứng dụng Access' bắt đầu bởi DoHung, 18 Tháng sáu 2006.

5,776 lượt xem

  1. DoHung

    DoHung Thành viên hoạt động

    Bài viết:
    211
    Đã được thích:
    0
    Nơi ở:
    Hanoi
    Cao thủ nào biết dòng lệnh để tạo link table bằng VB thì giới thiệu cho mình với.
    Cám ơn các bạn
     
    #1
  2. Song Huong

    Song Huong Thành viên thân thiết

    Bài viết:
    875
    Đã được thích:
    2
    Nơi ở:
    Hỏi quê, rằng mộng ban đầu đã xa
    Giả sử bạn có 02 bảng
    Inventory(InvtID, Descr, UOM)
    InTran(InvtID, TranDate, Qty, TranAmt)

    Bạn muốn chọn những mặt hàng phát sinh từ ngày BegDate đến EndDate
    với các field InvtID, Descr, UOM, Qty, TranAmt từ 02 bảng. Bạn viết câu SQL như sau:

    Select t.InvtID, i.Descr, i.UOM, t.Qty, t.TranAmt
    From Inventory i Inner Join InTran t On i.InvtID = t.InvtID
    Where t.TranDate Between BegDate And EndDate.

    Không biết như vậy có đúng ý bạn không?
    Thân.
     
    #2
  3. DoHung

    DoHung Thành viên hoạt động

    Bài viết:
    211
    Đã được thích:
    0
    Nơi ở:
    Hanoi
    Ý mình không phải vậy.
    Mình định link table từ một CSDL khác từ Access cơ.
    Mình đã tự tìm câu trả lời rồi. Đây

    DoCmd.TransferDatabase acLink, "Microsoft Access", Ddan, acTable, "DanhMuc", "DanhMuc"

    Cám ơn bạn
     
    #3
  4. hai2hai

    hai2hai VNUNI Makes a difference

    Bài viết:
    2,012
    Đã được thích:
    128
    Nơi ở:
    Hà nội
    modAttachTables

    Đây là code cũ của mình từ cách đây hơn 10 năm rồi nên thời đó mình dùng DAO.
    Copy and cut đoạn sau và lưu vào file có tên là modAttachTables.bas
    (Muốn copy có cấu trúc thì dùng nút Quote trên diễn đàn nhé)
    ----------------------------------------------------------------------

    Attribute VB_Name = "modAttachTables"
    'Option Explicit

    '----------------------------------------------------------------------
    ' GetAttachedDBPath
    '
    ' Returns the path of the attached table's .MDB. If the attached
    ' table is not an Access table, or if the table specified by
    ' AttachedTableName is a local table, then this function will
    ' return an empty string ("").
    '----------------------------------------------------------------------
    Function GetAttachedDBPath(AttachedTableName) As String
    On Error GoTo GetAttachedDBPath_Err

    Const ATTACHED_TABLE_PREFIX = ";DATABASE="
    Dim AttachedDBPath As String ' The attached path
    Dim DBStrLength As Integer ' Length of the Connect string prefix
    Dim db As Database ' Current Database
    DBStrLength = Len(ATTACHED_TABLE_PREFIX)

    ' Retrieve the full connect string.

    Set db = DBEngine.Workspaces(0).OpenDatabase(DataPath & DATA_ATTACH_FILE)

    AttachedDBPath = db(AttachedTableName).Connect

    ' If this is a Connect string for an Access database, then
    ' strip out the path, otherwise return the empty string.

    If (left$(AttachedDBPath, DBStrLength) = ATTACHED_TABLE_PREFIX) Then
    AttachedDBPath = right$(AttachedDBPath, Len(AttachedDBPath) - DBStrLength)
    Else
    AttachedDBPath = ""
    End If

    GetAttachedDBPath_Exit:
    GetAttachedDBPath = AttachedDBPath
    Exit Function

    GetAttachedDBPath_Err:
    Screen.MousePointer = 0
    ErrorMsg "GetAttachedDBPath", "modAttachTables", Err.Number, Err.Description
    AttachedDBPath = ""
    Resume GetAttachedDBPath_Exit

    End Function

    '----------------------------------------------------------------------
    ' AttachTables
    '
    ' Attaches tables to the database specified in FileName.
    ' This function returns TRUE if successful.
    '----------------------------------------------------------------------
    Function AttachTables(FileName As String) As Integer
    On Error GoTo AttachTables_Err

    Dim db As Database
    Dim td As TableDef
    Dim i As Integer

    Set db = DBEngine.Workspaces(0).OpenDatabase(DataPath & DATA_ATTACH_FILE)

    ' Initialize progress meter.

    ' Display the splash screen during intialization
    DisplaySplash True
    DoEvents 'ensures that the splash screen will get a chance to repaint
    Screen.MousePointer = vbHourglass ' Wait

    ' Loop through all tables, reattaching those with nonzero-length
    ' Connect strings. Tables with zero-length Connect strings are
    ' local tables, not attached tables.

    For i = 0 To db.TableDefs.Count - 1
    Set td = db.TableDefs(i)
    If db.TableDefs.Count - 1 = 0 Then
    Percent% = 100
    Else
    Percent% = Int((i / (db.TableDefs.Count - 1)) * 100)
    End If

    ' If this is an attached table, try to reattach it.
    If td.Connect <> "" Then
    td.Connect = ";DATABASE=" & FileName
    On Error Resume Next
    td.RefreshLink
    On Error GoTo AttachTables_Err
    If Err <> 0 Then
    MsgBox "File '" & FileName & "' does not contain required table(s)'" & td.SourceTableName & "'", 16, "Incorrect Database"
    AttachTables = False
    GoTo AttachTables_Exit:
    End If

    End If
    Progress Percent%, ""

    Next i

    AttachTables = True

    AttachTables_Exit:
    On Error Resume Next
    DisplaySplash False
    Screen.MousePointer = vbDefault
    db.Close
    Exit Function

    AttachTables_Err:
    Screen.MousePointer = vbDefault
    ErrorMsg "AttachTables", "modAttachTables", Err.Number, Err.Description
    AttachTables = False
    Resume AttachTables_Exit

    End Function


    '----------------------------------------------------------------------
    ' AreTablesAttached
    '
    ' Returns TRUE if valid attachments to the back-end database exist.
    '----------------------------------------------------------------------
    Function AreTablesAttached(sAttachTableName As String) As Integer
    On Error GoTo AreTablesAttached_Err
    Dim db As Database

    Set db = DBEngine.Workspaces(0).OpenDatabase(DataPath & DATA_ATTACH_FILE)

    ' Ignoring errors, try to open a recordset
    ' on a table in the back-end database.

    On Error Resume Next
    ' db.TableDefs(GetConfigItem(CONFIG_ID_ATTACHED_TABLE_NAME)).RefreshLink
    db.TableDefs(sAttachTableName).RefreshLink

    ' If we hit an error (i.e. Err <> 0) then
    ' the tables were not attached.

    AreTablesAttached = (Err = 0)

    On Error GoTo AreTablesAttached_Err

    ' Clean up

    db.Close

    AreTablesAttached_Exit:
    Exit Function

    AreTablesAttached_Err:
    ErrorMsg "AreTablesAttached", "modAttachTables", Err.Number, Err.Description
    AreTablesAttached = False
    Resume AreTablesAttached_Exit

    End Function
     
    #4
  5. hai2hai

    hai2hai VNUNI Makes a difference

    Bài viết:
    2,012
    Đã được thích:
    128
    Nơi ở:
    Hà nội
    Sử dụng đoạn code trong Main.bas:
    -------------------------------------------------

    Function IsAttachedOK() As Boolean
    On Error GoTo IsAttachedOK_Error
    IsAttachedOK = True
    If Not AreTablesAttached(TABLE_TO_ATTACT) Then
    With frmSplash.CMDialog1
    .Filter = "Database (*.mdb)|*.mdb|All files(*.*)|*.*||"
    .FileName = DATA_FILE
    .DialogTitle = "Locate Back-end database"
    .CancelError = True
    On Error GoTo Cancel_Error
    .ShowOpen
    If Not AttachTables(.FileName) Then GoTo IsAttachedOK_Error
    End With
    End If
    Done:
    Exit Function
    IsAttachedOK_Error:
    IsAttachedOK = False
    GoTo Done
    Cancel_Error:
    IsAttachedOK = False
    GoTo Done
    End Function

    Sub Main()
    IsLogon = False

    frmWelcome.Show
    DoEvents
    SetPathFirst
    If IsAttachedOK Then
    AttachDataPath = GetAttachedDBPath(TABLE_TO_ATTACT)
    If gfLng_DB_DAO_OpenDatabase(p_DbMain, "", DataPath + DATA_ATTACH_FILE, , False, 0, "", "") = 0 Then
    frmLogin.Show
    Else
    smsg = "Không thể mở được CSDL: " & "\...\Data\" + DATA_ATTACH_FILE '// Viết đoạn text tiếng việt trên = TCVN3 nhé, mình gõ = Unicode cho dễ đọc thôi
    MsgBox smsg, vbCritical, App.Title
    Shutdown '// Close App
    End If
    Unload frmWelcome
    frmLogin.Show
    Else
    Shutdown
    End If
    End Sub
    -------------
    Đó là code cũ của mình, cậu có thể thay đổi tùy theo ứng dụng của mình nhé.

    Cheers!
     
    #5
  6. hai2hai

    hai2hai VNUNI Makes a difference

    Bài viết:
    2,012
    Đã được thích:
    128
    Nơi ở:
    Hà nội
    DoHung ơi, MDB thì chạy được trên mạng (nhưng ko phải bao nhiêu Users cùng truy cập vào cùng 1 lúc cũng được đâu, nhất là trường hợp cậu cho phép nhiều người cùng thực hiện edit 1 chứng từ nào đó chẳng hạn rồi đều cho họ ghi lại). Đặc biệt theo lý thuyết thì nếu cho phép sửa ID của record và mọi thứ đều cascade được thì nhiều chuyện khi khoảng hơn 20 người cùng vào 1 bản ghi để làm việc đó (Ví dụ thế này: 1 người đang sửa ID của nhân viên có ID là 001 thành ID là 002, 1 người khác thì trước đó lại đang sửa diễn biến lương của nhân viên có ID là 001 (vẫn mã cũ mà người kia chưa sửa), vậy quan trọng là PM phải quản lý được vấn đề đó).


    Với lại, MDB, XLS, Fox, v.v... là desktop database nên đều phải sharefull thư mục (kể cả cái MDB gốc để link tới cũng phải sharefull) nên đó là sự khác nhau giữa các Client/Server DB Engine (như mySQL, MS SQL, Oracle...) và Desktop DB Engines. Vì thế cái chức năng ... "chạy trên nhiều máy một cách ... vô tư" thì thường nên nói be bé thôi :) (chủ yếu nói khi KH hỏi) vì giả sử khi sharefull thư mục DB thì vấn đề gì xảy ra khi có người vào...delete DB file?

    Chúc DoHung hoàn thiện SP ngày càng sớm.
     
    #6
  7. DoHung

    DoHung Thành viên hoạt động

    Bài viết:
    211
    Đã được thích:
    0
    Nơi ở:
    Hanoi
    Cám ơn anh Hai2hai,
    Về vụ chạy qua mạng bị "vấn đề", thấy nhiều diễn đàn thảo luận.
    Thực sự mà nói, xác suất sảy ra là rất nhỏ để 2 người cùng vào một record và save cùng lúc tính theo đơn vị giây.
    Mình nhớ không nhầm đã đọc ở đâu đó, access 2003 đã giải quyết tốt vấn đền này rồi.
    Hiện tại mình dùng tính năng tách phần CSDL (Table) và ứng dụng (Forms, Query, report). Các máy trạm chỉ chạy trên ứng dụng thôi còn CSDL thì để trên mạng.
    Thực tế mình đã viết rất nhiều phần mềm (không chỉ kế toán) khoảng hơn 10 người dùng chạy với tần xuất tương đối lớn nhưng chưa hề gặp phải vấn đề gì cả. (Cõ lẽ chưa đến lúc).
    Nhưng cũng rút kinh nghiệm để nói nho nhỏ thôi.

    Cám ơn anh hai2hai.
     
    Last edited: 19 Tháng sáu 2006
    #7
  8. hai2hai

    hai2hai VNUNI Makes a difference

    Bài viết:
    2,012
    Đã được thích:
    128
    Nơi ở:
    Hà nội
    Cách làm như vậy là đúng rồi. Chương trình nằm trên 1 MDB, dữ liệu nằm trên 1 MDB khác. File MDB chương trình thì attach tables từ file dữ liệu.

    Chú ý: Cần phải kiểm tra link attached tables (chỉ cần kiểm tra 1 link tới 1 table thôi) trước khi chạy chương trình. Nếu ko thấy attach chứng tỏ là filepath tới dữ liệu gốc đã invalid (có thể là tên file đã thay đổi hoặc bị move đi đâu đó, hoặc đường mạng ko kết nối). Từ hồi Access 2.0 (office 4.3) mình đã làm như thế.

    Làm trên Access thì có thể tách chương trình & dữ liệu ra. Còn thực tế khi làm trên các ngôn ngữ lập trình thực sự thì nên thiết kế thành nhiều components riêng biệt như: Component về báo cáo, component vể quản trị bảo mật, component về quản lý danh mục, component về từng nghiệp vụ riêng. Khi đó trong chương trình chính chỉ sử dụng các components đó thôi. Như vậy, phần chương trình được tách ra thành nhiều components. Kiến trúc đó giống như một khối rubic, cục nào hỏng hoặc cần nâng cấp thì ta sửa chữa và thay nó mà ko ảnh hưởng đến các cục khác và ảnh hưởng tới toàn bộ chương trình.

    Nhưng dẫu sao, mdb vẫn ko phải là client/server đâu, DoHung thử dùng MSDE (engine của MS SQL) cài lên xem sao.
     
    #8
  9. DoHung

    DoHung Thành viên hoạt động

    Bài viết:
    211
    Đã được thích:
    0
    Nơi ở:
    Hanoi
    Dòng lệnh để kiểm tra link attached tables như thế nào hả anh hai2hai? Em chưa biết làm vụ này nhờ anh chỉ giùm

    Vụ này cũng chưa biết cách luôn. Anh hai2hai co tài liệu không?

    Cám ơn anh
     
    #9
  10. hai2hai

    hai2hai VNUNI Makes a difference

    Bài viết:
    2,012
    Đã được thích:
    128
    Nơi ở:
    Hà nội
    DoHung xem đoạn code anh post ở trên nhé. Có cả rồi đấy (tuy nhiên đoạn đó dùng DAO, em chuyển sang ADO nhé)

    MSDE hả, đơn giản thôi. Em kiếm vài quyển sách eBooks về MS SQL, rồi cài MS SQL lên. Làm quen với MS SQL đã, còn cái MSDE chỉ là cái Engine của MS SQL thôi (MSDE là bản free của MS, cho phép từ 10 đến 15 concurent users connected to DB at the same time. Hầu hết các ứng dụng nhỏ ở VN chỉ cần sài cái MSDE là vừa đủ, tiện cài đặt với kích cỡ bộ cài khoảng hơn 40Mb).
    Tuy nhiên, vì MSDE là engine nên nó ko có công cụ để quản lý database, vì thế thường khi cài MSDE lên thì người ta hay phải kiếm cái công cụ MSDE Manager để làm việc với DB cho tiện (Nhất là lúc test các câu lệnh SQL).


    Ở bộ .NET thì MS SQL 2005 Express cũng chính là bản tương tự như MSDE, cũng Free, Express, và 10 đến 15 concurent users.

    Nếu DoHung ở HN thì qua chỗ anh chơi, địa chỉ ở trang web. Anh sẽ copy MSDE, DbaMGR2k (1 công cụ kiểu MSDE Manager), và guidline cách chuyển ứng dụng chạy trên MS SQL.
     
    Last edited: 22 Tháng sáu 2006
    #10
  11. DoHung

    DoHung Thành viên hoạt động

    Bài viết:
    211
    Đã được thích:
    0
    Nơi ở:
    Hanoi
    Trời, nghe anh nói em thấy tróng mặt quá. Ngồi bệt cả xuống đất.
    Nếu setup hơi phức tạp như vậy thì khó phổ cập phần mềm lắm.
    Trình độ tin học của dân kế toán ở VN cũng chưa cáo lắm (Nói thật đấy).

    Nhưng dù sao cũng cám ơn anh.
    Anh cho địa chỉ, lúc nào rỗi thì em qua nhé.

    Cám ơn anh
     
    #11
  12. hai2hai

    hai2hai VNUNI Makes a difference

    Bài viết:
    2,012
    Đã được thích:
    128
    Nơi ở:
    Hà nội
    Cài cái công cụ đó là dùng cho nhà phát triển thôi. Với khách hàng thì em phải làm bộ cài cho họ cài từ đầu đến cuối chứ (bao gồm cài MSDE, create 1 cái DB của ứng dụng trên đó - cái đó bộ cài phải tự làm hết, rồi cài ứng dụng của mình vào - nên viết trên VB cho nhanh và dễ). Khách hàng ko cần tool tiệc gì cả em ạ.

    Anh làm bộ cài KH cũng chỉ cần nhắm mắt là cài được em ạ. Dĩ nhiên, để làm được như vậy thì công việc của mình phải nhiều hơn thôi.
     
    #12

Chia sẻ trang này