Đánh giá chủ đề:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Về các field (cột dữ liệu) có kiểu là OLE Object
#1
Chào các Bạn,
Theo dõi các bài viết trên diễn đàn tôi thấy có một số Bạn đã có nhầm lẫn các cột dữ liệu có kiểu dữ liệu là OLE Object với cột dữ liệu có kiểu Text, nên khi viết mã VBA đã viết tương tự như sau, với cột Lv có kiểu OLE Object:
Mã:
...
tbRec!Lv.Value = "Long binary data"
...
Dĩ nhiên khi chạy, đoạn code VBA trên sẽ nhận được thông báo lỗi hệ thống.
Trong một Microsoft Access Database, OLE Object (Object Linking and Embedding) là một kiểu dữ liệu đặc biệt, kiểu dữ liệu này không phải là Text, mà chính là 1 đối tượng (Object) của ứng dụng bên ngoài MS. Access mà nội dung là nội dung vật lý của file nhị phân (binary file), chẳng hạn như nội dung nhị phân (binary) của 1 ảnh, nội dung nhị phân của 1 file nhạc, nội dung nhị phân của 1 file video ...
Với các cột dữ liệu có kiểu OLE Object, khi ta mở bảng ra theo dạng trình bày cột và hàng, sẽ thấy hiện nội dung là một đoạn text với nội dung là "Long binary data". Đoạn text này chỉ là nội dung chỉ dẫn của MS. Access cho ta biết đó là kiểu dữ liệu OLE Object và chưa được nạp nội dung vào, chứ hoàn toàn không phải là nội dung dữ liệu của cột dữ liệu này. Nếu cột OLE Object đã được nạp nội dung, khi xem ở dạng bảng như trên thì sẽ hiển thị dòng text chỉ rõ OLE Object đó là gì, thí dụ như nếu đó là 1 ảnh thì đoạn text hiển thị là "Bitmap image"
Các Bạn xem các ảnh sau đây để hiểu rõ hơn về nội dung tôi trình bày ở trên:

Cấu trúc bảng Categories (trong dữ liệu mẫu Northwind):
[Hình: 188uayq6z7yyynb4g.jpg]

Và bảng Categories được mở dưới dạng hàng + cột:
[Hình: yq6919nhofnef9d4g.jpg]

Cấu trúc bảng hệ thống MSysObjects:
[Hình: 9my8e0a4928r2m34g.jpg]

Và bảng MSysObjects được mở dưới dạng hàng + cột:
[Hình: e8up2v1ju2fwsdu4g.jpg]

Trong bài kế tiếp, tôi sẽ trình bày cách thức để cho hiển thị nội dung biểu kiến của cột OLE Object này trong MS. Access.
"Nội dung biểu kiến" nghĩa là nội dung ta có thể nhìn thấy được theo đặc trưng và tính chất của OLE Object. Ví dụ như thấy được ảnh của 1 Bitmap Image, ... Tôi phải dài dòng như vậy để các Bạn phân biệt với nội dung nhị phân của 1 OLE Object.
Chữ ký của lehongduc Lê Hồng Đức
Số ĐT: 0913.941.144
Email: lhongduc@gmail.com, lehongduc@quantribanhang.vn
Website: http://quantribanhang.vn
Reply
Những người đã cảm ơn ongke0711 , maidinhdan , cpucloi
#2
Chào các Bạn,
Hôm nay tôi xin được trao đổi tiếp với các Bạn về sử dụng OLE Object trong MS. Access.
Như tôi đã trình bày trong bài trước, OLE Object là những Object của các ứng dụng bên ngoài MS. Access, được ta "mang vào" lưu và truy xuất chúng ngay bên trong file database của MS. Access. 

Sau đây là cách lưu 1 OLE Object vào 1 table của MS. Access:
- Lưu trực tiếp vào table bằng lệnh "Insert Object" của MS. Access:
+ Mở table ra dưới dạng cột và hàng
+ Bấm nút chuột phải tại ô dữ liệu (cột dữ liệu OLE Object) làm hiện menu tắt rồi chọn mục lệnh "Insert Object" làm hiện cửa sổ chức năng giúp chúng ta chọn kiểu OLE Object và chọn 1 OLE Object xác định như ảnh bên dưới:
[Hình: 26446xhp9n0skyn4g.jpg]

[Hình: 8hb9vd989ck62e04g.jpg]

Ở ảnh trên, chúng ta thấy có khung liệt kê các kiểu OLE Object cụ thể (như: Bitmap Image, Microsoft Excel Chart, Microsoft Excel Worksheet, ...). Chỉ những OLE nào đã được đăng ký hợp lệ với Windows mới được liệt kê trong cửa sổ này.
Trên cửa sổ này:
+ ta chọn Create New: nếu muốn chèn 1 Object mới sẽ do chính chúng ta tạo ra ngay sau khi bấm nút "OK" trên cửa sổ này. Khi đó, ứng dụng tương ứng với kiểu OLE Object sẽ được khởi động để ta tạo 1 tài liệu mới trong ứng dụng đó, để chèn vào bảng đang mở trong MS. Access
+ ta chọn Create From File: nếu muốn chèn 1 Object đã có sẵn từ 1 file, để chèn vào bảng đang mở trong MS. Access. Nếu chọn mục này, không bắt buộc kiểu OLE tương ứng với file đã chọn phải được đăng ký hợp lệ với Windows.

Thao tác thì rất đơn giản, nhưng thực hiện có thành công hay không lại phụ thuộc vào rất nhiều yếu tố riêng của từng máy tính và bản Windows đang sử dụng. 

- Vậy chúng ta có nên sử dụng kiểu dữ liệu OLE Object này hay không? 
Nên hay không nên sử dụng OLE Object là tùy vào trường hợp và nhu cầu cụ thể của các Bạn. 
Tuy nhiên, nếu không phải là giải pháp cuối cùng thì thay vì chèn nội dung nhị phân của 1 OLE Object, chúng ta chỉ nên lưu lại tên file để truy xuất khi cần. Tất nhiên, khi ta chỉ lưu tên file thôi (như file ảnh của nhân sự chẳng hạn) thì file này phải có sẵn khi ứng dụng của chúng ta hoạt động.

Nếu lưu sẵn nội dung nhị phân của 1 file OLE vào table trong MS. Access:
+ khi nội dung OLE Object đó thay đổi, chúng ta phải làm thao tác "Insert Object" lại như từ đầu để cập nhật lại nội dung thay đổi đó. 
+ đòi hỏi Bạn phải bảo đảm chắc chắn rằng các thao tác truy xuất nội dung table (Open - mở, Read - đọc, Write - ghi) không làm hỏng nội dung nhị phân đã lưu đó.

Một diều lưu ý nữa là: nếu ta lưu nội dung nhị phân của file OLE Object như vậy vào table sẽ làm cho kích thước của file database của chúng ta phình to lên rất nhiều. Điều này chính là nỗi lo lớn của chúng ta khi thiết kế 1 ứng dụng đó các Bạn.

Trong bài kế tiếp tôi sẽ trình bày cách viết mã VBA để đọc nội dung nhị phân của 1 file vào 1 table và ghi thành file ngoài từ nội dung nhị phân đã lưu trong 1 table.
Chữ ký của lehongduc Lê Hồng Đức
Số ĐT: 0913.941.144
Email: lhongduc@gmail.com, lehongduc@quantribanhang.vn
Website: http://quantribanhang.vn
Reply
Những người đã cảm ơn cpucloi
#3
Chào các Bạn,
Trong bài này chúng ta sẽ tìm hiểu cách thức đọc vào và ghi ra thành file nội dung nhị phân của 1 OLE Object trong MS. Access
Như trong bài trước đã trình bày với các Bạn, OLE Object thực chất là nội dung nhị phân của tài liệu thuộc ứng dụng bên ngoài MS. Access được lưu vào bên trong 1 table của MS. Access database. OLE Object như vậy thậm chí có thể là 1 file thực thi.

Với VBA chúng ta có thể thực hiện việc đọc vào 1 nội dung (từ 1 file bên ngoài MS. Access) và ghi ra thành 1 file từ nội dung đã lưu trong MS. Access database. 

Sau đây là code VBA để chúng ta làm những việc đó (nguồn từ Microsoft)
Link nguồn: https://support.microsoft.com/en-us/help...ects-blobs

- Đọc nội dung 1 file ngoài và lưu vào 1 table trong MS. Access
với Function ReadBLOB(Source As String, T As DAO.Recordset, sField As String)

Giải thích cú pháp của Function ReadBLOB:
+ Source: tên file nguồn với đường dẫn đầy đủ (thí dụ: "C:\MYPRO\mydata.dat")
+ T: Recordset Object (để truy xuất đến 1 bảng dữ liệu của Database)
+ sField: tên của cột dữ liệu có kiểu OLE Object, là nơi ta sẽ lưu nội dung nhị phân của Source vào đó.

Mã:
Function ReadBLOB(Source As String, T As DAO.Recordset, _
sField As String)
    Dim NumBlocks As Integer, SourceFile As Integer, i As Integer
    Dim FileLength As Long, LeftOver As Long
    Dim FileData As String
    Dim RetVal As Variant

    On Error GoTo Err_ReadBLOB

    ' Open the source file.
    SourceFile = FreeFile
    Open Source For Binary Access Read As SourceFile

    ' Get the length of the file.
    FileLength = LOF(SourceFile)
    If FileLength = 0 Then
        ReadBLOB = 0
        Exit Function
    End If

    ' Calculate the number of blocks to read and leftover bytes.
    NumBlocks = FileLength \ BlockSize
    LeftOver = FileLength Mod BlockSize

    ' SysCmd is used to manipulate status bar meter.
    RetVal = SysCmd(acSysCmdInitMeter, "Reading BLOB", _
             FileLength \ 1000)

    ' Put first record in edit mode.
    T.MoveFirst
    T.Edit

    ' Read the leftover data, writing it to the table.
    FileData = String$(LeftOver, 32)
    Get SourceFile, , FileData
    T(sField).AppendChunk (FileData)

    RetVal = SysCmd(acSysCmdUpdateMeter, LeftOver / 1000)

    ' Read the remaining blocks of data, writing them to the table.
    FileData = String$(BlockSize, 32)
    For i = 1 To NumBlocks
        Get SourceFile, , FileData
        T(sField).AppendChunk (FileData)

        RetVal = SysCmd(acSysCmdUpdateMeter, BlockSize * i / 1000)
    Next i

    ' Update the record and terminate function.
    T.Update
    RetVal = SysCmd(acSysCmdRemoveMeter)
    Close SourceFile
    ReadBLOB = FileLength
    Exit Function

Err_ReadBLOB:
    ReadBLOB = -Err
    Exit Function

End Function

- Ghi nội dung OLE Object từ MS. Access ra thành 1 file bên ngoài
với Function WriteBLOB(T As DAO.Recordset, sField As String, Destination As String)

Giải thích cú pháp của Function WriteBLOB:
+ T: Recordset Object (để truy xuất đến 1 bảng dữ liệu của Database, nơi đang lưu nội dung OLE Object. 
+ sField: tên của cột dữ liệu trong bảng dữ liệu nơi đang lưu nội dung OLE Object cần ghi ra thành file ngoài.
+ Destination: tên file được ghi thành, với đường dẫn đầy đủ.

Mã:
Function WriteBLOB(T As DAO.Recordset, sField As String, _
Destination As String)
    Dim NumBlocks As Integer, DestFile As Integer, i As Integer
    Dim FileLength As Long, LeftOver As Long
    Dim FileData As String
    Dim RetVal As Variant

    On Error GoTo Err_WriteBLOB

    ' Get the size of the field.
    FileLength = T(sField).FieldSize()
    If FileLength = 0 Then
        WriteBLOB = 0
        Exit Function
    End If

    ' Calculate number of blocks to write and leftover bytes.
    NumBlocks = FileLength \ BlockSize
    LeftOver = FileLength Mod BlockSize

    ' Remove any existing destination file.
    DestFile = FreeFile
    Open Destination For Output As DestFile
    Close DestFile

    ' Open the destination file.
    Open Destination For Binary As DestFile

    ' SysCmd is used to manipulate the status bar meter.
    RetVal = SysCmd(acSysCmdInitMeter, _
    "Writing BLOB", FileLength / 1000)

    ' Write the leftover data to the output file.
    FileData = T(sField).GetChunk(0, LeftOver)
    Put DestFile, , FileData

    ' Update the status bar meter.
    RetVal = SysCmd(acSysCmdUpdateMeter, LeftOver / 1000)

    ' Write the remaining blocks of data to the output file.
    For i = 1 To NumBlocks
        ' Reads a chunk and writes it to output file.
        FileData = T(sField).GetChunk((i - 1) * BlockSize _
           + LeftOver, BlockSize)
        Put DestFile, , FileData

        RetVal = SysCmd(acSysCmdUpdateMeter, _
        ((i - 1) * BlockSize + LeftOver) / 1000)
    Next i

    ' Terminates function
    RetVal = SysCmd(acSysCmdRemoveMeter)
    Close DestFile
    WriteBLOB = FileLength
    Exit Function

Err_WriteBLOB:
    WriteBLOB = -Err
    Exit Function

End Function
Chữ ký của lehongduc Lê Hồng Đức
Số ĐT: 0913.941.144
Email: lhongduc@gmail.com, lehongduc@quantribanhang.vn
Website: http://quantribanhang.vn
Reply
Những người đã cảm ơn cpucloi


Có thể liên quan đến chủ đề
Chủ đề: Tác giả Trả lời: Xem: Bài mới nhất
  Cập nhật dữ liệu vào combobox ChiMai 1 123 09-09-18, 09:34 PM
Bài mới nhất: cpucloi
  Cập nhật dữ liệu vào 2 table cùng một lúc ChiMai 1 291 05-06-18, 04:18 PM
Bài mới nhất: tranthanhan1962
  Import dữ liệu từ excel vào access ChiMai 3 422 25-05-18, 08:31 AM
Bài mới nhất: domfootwear
  Hướng Dẫn Cách lưu (back up database) dữ liệu! danhxetnghiem 38 10,612 12-05-18, 11:46 AM
Bài mới nhất: MTNQ
  chia sẻ dữ liệu db access qua mạng LAN. tuanvu2409 5 775 02-02-18, 12:41 AM
Bài mới nhất: tranthanhan1962

Chuyển nhanh:


User(s) browsing this thread: 1 Guest(s)
Diễn Đàn Thơ Văn Thi Ẩm Lâu|Nhà Hàng Sông Thơ| PMA Nha Trang| Gỗ Acrylic Không Đường Line