Đố vui về ADO, DAO. (2 người xem)

Liên hệ QC

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

Lâu quá không thấy ai tham dự đề tài đố vui về ADO/DAO, để khởi động lại. nay tôi xin đố các bạn là không dùng vòng lặp, clipboard mà ta có thể đổ dữ liệu thành 1 bảng ở trình soạn email outlook.
1. Bảng dữ liệu:

upload_2018-1-3_9-44-6.png

2. Điều kiện để đưa dữ liệu vào outlook là TP=B.
3. Kết quả như sau:

upload_2018-1-3_9-42-55.png

 

File đính kèm

Lần chỉnh sửa cuối:
Lâu quá không thấy ai tham dự đề tài đố vui về ADO/DAO, để khởi động lại. nay tôi xin đố các bạn là không dùng vòng lặp, clipboard mà ta có thể đổ dữ liệu thành 1 bảng ở trình soạn email outlook.
1. Bảng dữ liệu:

View attachment 189195

2. Điều kiện để đưa dữ liệu vào outlook là TP=B.
3. Kết quả như sau:

View attachment 189194

1 tuần = 7 ngày đã trôi qua, nhưng chỉ thấy có 2 lần tải, có vẻ như mọi người không quan tâm đến đề bài này. :(
 
DAO và ADO đã được đưa vào sách Lập trình VBA tập 2 một cách hệ thống ở mức độ cơ bản nhất. Khi đó sẽ nhiều người nghiên cứu món này hơn, anh chuẩn bị tinh thần đi :)
 
1 tuần = 7 ngày đã trôi qua, nhưng chỉ thấy có 2 lần tải, có vẻ như mọi người không quan tâm đến đề bài này. :(

Office của bà con là phiên bản lậu cho nên ngại dùng Outlook để thử.
Bạn ra luôn lời giải cho rồi. Sau khi có lời giải, bà con sẽ đố tiếp về việc dùng lời giải ấy để áp dụng vào cái khác.
 
Office của bà con là phiên bản lậu cho nên ngại dùng Outlook để thử.
Bạn ra luôn lời giải cho rồi. Sau khi có lời giải, bà con sẽ đố tiếp về việc dùng lời giải ấy để áp dụng vào cái khác.
Nếu vậy em gửi đáp án luôn.

Code này sẽ rất quen thuộc nếu ai đã từng lập trình web để đổ dữ liệu xuống table từ CSDL.

Mã:
Sub DoVui_ADO()
    Dim objOutlook, objOutlookMsg, cn, rst As Object
    Set objOutlook = CreateObject("Outlook.Application")
    Set objOutlookMsg = objOutlook.CreateItem(0)
    Set cn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    rst.Open ("select * from [Sheet1$] where TP='B'"), cn
    With objOutlookMsg
        .To = "hailuamientay@giaiphapexcel.com"
        .Subject = Sheet2.[B1]
        .HTMLBody = "<strong>Xin chào các ban ,</strong> <br><br>" & Sheet2.[B2] & "<br><table border='1'><th>No</th><th>TP</th><th>ITEM NAME</th><th>SPEC</th><th>COLOR</th><th>Q'TY</th> <tr>" & rst.GetString(, , "</td><td>", "</tr><tr>") & "</tr></table><br><a href=http://www.giaiphapexcel.com/diendan/threads/%C4%90%E1%BB%91-vui-v%E1%BB%81-ado-dao.80367/page-15#post-835345/>Xem thêm tai dây</a><br><strong>Hai Lúa Miên Tây</strong>"
        .Display
    End With
End Sub
 

File đính kèm

Để tiếp tục, tôi xin ra tiếp câu đố là không dùng vòng lặp, làm sao ta có thể đưa kết quả vào Shape như hình bên dưới:

upload_2018-1-22_11-9-7.png
 

File đính kèm

Cũng đã gần cuối tuần rồi, mọi người chuẩn bị đi bão nên cũng không mấy quan tâm nhỉ. Các bạn giải đáp nhanh để ta tiếp tục với câu đố tiếp theo nhé.
Giờ người ta không thích kiểu đố đố như thế này nữa, có thể vì:
Hoặc là giúp bài có ích - thành viên đang chờ
Hoặc là làm hoạt động gì đó ra tiền
Hoặc là bài đố phải có ứng dụng thực tiễn thật sự, thay vì chỉ vui
 
Giờ người ta không thích kiểu đố đố như thế này nữa, có thể vì:
Hoặc là giúp bài có ích - thành viên đang chờ
Hoặc là làm hoạt động gì đó ra tiền
Hoặc là bài đố phải có ứng dụng thực tiễn thật sự, thay vì chỉ vui
Vậy GPE mình cần thêm mục "Đố vui có thưởng" rồi. :p:p
 
Giờ người ta không thích kiểu đố đố như thế này nữa, có thể vì:
Hoặc là giúp bài có ích - thành viên đang chờ
Hoặc là làm hoạt động gì đó ra tiền
Hoặc là bài đố phải có ứng dụng thực tiễn thật sự, thay vì chỉ vui
Ứng dụng cho bài này là có thể lấy dữ liệu đưa vào một cái nút nhấn được tạo = Shape, hoặc có thể dùng shape để trình bày dữ liệu.
 
Để tiếp tục, tôi xin ra tiếp câu đố là không dùng vòng lặp, làm sao ta có thể đưa kết quả vào Shape như hình bên dưới:

View attachment 190543
Em xin đưa phương án như sau, anh góp ý nhé
Mã:
Sub DoVui_ADO()
    Set cn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    lsql = "SELECT DISTINCT [TP] & '-> ' & [GR] & '-> ' & Sum([QTY]) & 'PCS' AS [Sum Of QTY] FROM [Sheet1$] GROUP BY TP, GR"
    rst.Open lsql, cn
    Do While rst.EOF = False
        strValue = strValue & rst.Fields("Sum Of QTY").Value & Chr(10)
        rst.MoveNext
    Loop
    ActiveSheet.Shapes("Rec").TextFrame2.TextRange.Characters.Text = strValue
End Sub
 
Em xin đưa phương án như sau, anh góp ý nhé
Mã:
Sub DoVui_ADO()
    Set cn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    lsql = "SELECT DISTINCT [TP] & '-> ' & [GR] & '-> ' & Sum([QTY]) & 'PCS' AS [Sum Of QTY] FROM [Sheet1$] GROUP BY TP, GR"
    rst.Open lsql, cn
    Do While rst.EOF = False
        strValue = strValue & rst.Fields("Sum Of QTY").Value & Chr(10)
        rst.MoveNext
    Loop
    ActiveSheet.Shapes("Rec").TextFrame2.TextRange.Characters.Text = strValue
End Sub
Rất cám ơn bạn đã tham gia. Nên thử lại là ta không dùng vòng lặp nhé bạn.
 
Rất cám ơn bạn đã tham gia. Nên thử lại là ta không dùng vòng lặp nhé bạn.
Nếu không vòng lặp em mạnh dạn đưa đáp án như thế này, anh xem và góp ý nhé.
Mã:
Sub DoVui_ADO()
    Set cn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    lsql = "SELECT DISTINCT [TP] & '-> ' & [GR] & '-> ' & Sum([QTY]) & 'PCS' AS [Sum Of QTY] FROM [Sheet1$] GROUP BY TP, GR"
    rst.Open lsql, cn
    strValue = rst.GetString(, , , Chr(10))
    ActiveSheet.Shapes("Rec").TextFrame2.TextRange.Characters.Text = strValue
End Sub
 
Nếu không vòng lặp em mạnh dạn đưa đáp án như thế này, anh xem và góp ý nhé.
Mã:
Sub DoVui_ADO()
    Set cn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    lsql = "SELECT DISTINCT [TP] & '-> ' & [GR] & '-> ' & Sum([QTY]) & 'PCS' AS [Sum Of QTY] FROM [Sheet1$] GROUP BY TP, GR"
    rst.Open lsql, cn
    strValue = rst.GetString(, , , Chr(10))
    ActiveSheet.Shapes("Rec").TextFrame2.TextRange.Characters.Text = strValue
End Sub
Đúng là như vầy rồi. Thật ra đây là cái mà mình muốn truyền tải cho mọi người (rst.GetString), nó ứng dụng rất nhiều chứ không phải đơn thuần chỉ là đố vui như bạn @Gió Đông nói.
Cám ơn bạn.
 
Nếu không vòng lặp em mạnh dạn đưa đáp án như thế này, anh xem và góp ý nhé.
Mã:
Sub DoVui_ADO()
    Set cn = CreateObject("ADODB.Connection")
    Set rst = CreateObject("ADODB.Recordset")
    cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
    lsql = "SELECT DISTINCT [TP] & '-> ' & [GR] & '-> ' & Sum([QTY]) & 'PCS' AS [Sum Of QTY] FROM [Sheet1$] GROUP BY TP, GR"
    rst.Open lsql, cn
    strValue = rst.GetString(, , , Chr(10))
    ActiveSheet.Shapes("Rec").TextFrame2.TextRange.Characters.Text = strValue
End Sub
Thật ra câu lệnh SQL như sau là đủ, bạn chỉnh sửa lại chút xíu nhé.

"select TP,GR,SUM(QTY) from [Sheet1$] GROUP BY TP,GR"
 
lâu lắm không thấy ai viết bài
Hôm nay Mạnh hỏi 1 chút
thông thường khi ta sử dung ADO để lấy dữ liệu từ 1 Sheet file đóng lên hay lấy dữ liệu vào Mảng ta hay sử dụng 2 dòng code cơ bản sau
Mã:
Set cn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
Vậy nếu ta chỉ sử dụng 1 dòng sau để Copy dữ liêu từ 1 Sheet lên hay lấy dữ cho vào mảng thì có chạy nhanh hơn 2 dòng trên kết hợp hay ko
và tại sao mong các Bạn chỉ dẫn
Mã:
Set rst = CreateObject("ADODB.Recordset")

Xin cảm ơn
 
Nhanh hay không chưa biết. Không có connection lấy gì đọc dữ liệu?
 
Nhanh hay không chưa biết. Không có connection lấy gì đọc dữ liệu?
Câu trả lời của Mình là ĐƯỢC .... TA không cần sử dụng connection hay chi tiết như sau ta vẫn có thể lấy dữ liệu lên Sheet hay mảng ok
Mã:
Set cn = CreateObject("ADODB.Connection")
Ta chỉ cần cơ bản 1 dòng sau là đủ để lấy dữ liệu lên Sheet hay lên Mảng
Mã:
Set rst = CreateObject("ADODB.Recordset")
Làm phiền @Hai Lúa Miền Tây cho xin 1 ý kiến cho bài 321 & 322 và bài này ... Mạnh Cảm Ơn
 
Câu trả lời của Mình là ĐƯỢC .... TA không cần sử dụng connection hay chi tiết như sau ta vẫn có thể lấy dữ liệu lên Sheet hay mảng ok
Mã:
Set cn = CreateObject("ADODB.Connection")
Ta chỉ cần cơ bản 1 dòng sau là đủ để lấy dữ liệu lên Sheet hay lên Mảng
Mã:
Set rst = CreateObject("ADODB.Recordset")
Làm phiền @Hai Lúa Miền Tây cho xin 1 ý kiến cho bài 321 & 322 và bài này ... Mạnh Cảm Ơn
Ta có thể khai báo và khởi tạo Object 1 trong 2 cái trên (Hoặc cn hoặc rst) đều có thể lấy được dữ liệu. Cho dù có dùng cách không khai báo và khởi tạo Object (Conection hay Recordset) thì theo tôi đã từng sử dụng thì tốc độ cũng không có khác biệt là mấy. Bởi vì nếu như anh không khởi tạo connection thì anh cũng phải dùng chuỗi kết nối với file nguồn trong thủ tục mở recordset.
 
Ta có thể khai báo và khởi tạo Object 1 trong 2 cái trên (Hoặc cn hoặc rst) đều có thể lấy được dữ liệu. Cho dù có dùng cách không khai báo và khởi tạo Object (Conection hay Recordset) thì theo tôi đã từng sử dụng thì tốc độ cũng không có khác biệt là mấy. Bởi vì nếu như anh không khởi tạo connection thì anh cũng phải dùng chuỗi kết nối với file nguồn trong thủ tục mở recordset.
Chính xác vậy và đây là code Mạnh Viết .. Nhờ HLMT coi dùm
Mã:
Private Sub CopyRecordset()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Cells.ClearContents
        Range("A1").CopyFromRecordset Rst
    End If
End Sub
Rem ==========
Private Sub GetDataGetRows()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    Dim dArr(), Arr(), i As Long, j As Long, k As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Arr = Rst.getrows(RecCount)
        ReDim dArr(1 To UBound(Arr, 2) + 1, 1 To UBound(Arr, 1) + 1)
        For i = 0 To UBound(Arr, 2)
            k = k + 1
            For j = 0 To UBound(Arr, 1)
                dArr(k, j + 1) = Arr(j, i)
            Next j
        Next i
        Cells.ClearContents
        Range("A2").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
    End If
End Sub
 
Chính xác vậy và đây là code Mạnh Viết .. Nhờ HLMT coi dùm
Mã:
Private Sub CopyRecordset()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Cells.ClearContents
        Range("A1").CopyFromRecordset Rst
    End If
End Sub
Rem ==========
Private Sub GetDataGetRows()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    Dim dArr(), Arr(), i As Long, j As Long, k As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Arr = Rst.getrows(RecCount)
        ReDim dArr(1 To UBound(Arr, 2) + 1, 1 To UBound(Arr, 1) + 1)
        For i = 0 To UBound(Arr, 2)
            k = k + 1
            For j = 0 To UBound(Arr, 1)
                dArr(k, j + 1) = Arr(j, i)
            Next j
        Next i
        Cells.ClearContents
        Range("A2").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
    End If
End Sub
Thì như tôi đã nói ở trên thôi, thông thường thì người ta bỏ khởi tạo recordset chứ ít ai bỏ khởi tạo connection. Dùng cách nào miễn mình quen và tránh xảy ra lỗi tiềm ẩn, kết quả đúng là được.
 
Khi mở một file để đọc, ADO coi như đó là một CSDL, và nó cần tạo một connection để kết nối. Cái lệnh Open mà bạn thấy nó chính thức gồm luôn Open Connection và Excute Command (lệnh SQL).
Khi chỉ cần đọc một lần, cái connection có thể được hiểu ngầm (implicit, trái với tường minh là explicit), đọc xong rồi bỏ. Kiểu giống như sử dụng các đối tượng bằng lệnh With CreateObject(...) - End With, cái Object đó được thành lập và bỏ sau lệnh End With.
Lý do tại sao phải mở connection tường minh (khai báo và set 1 cái object connection):
1. Khi cần đọc nhiều lần: một lần connect vào CSDL tốn tài nguyên, vì vậy nếu đọc nhiều lần thì nên giữ lại. Sau khi đọc xong thì đóng lại (huỷ đi). Hầu hết công việc mà các bạn làm ở đây chỉ đọc mỗi file 1 lần cho nên bạn chưa thấy nhu cầu này.
2. Khi CSDL thuộc loại có nhiều thủ tục (ví dụ SQL Server có admin của nó, chỉ cho phép 1 số tình trạng kết nối). Ngừoi dùng cần phân biệt lúc kết nối và lúc lấy dữ liệu để có thể debug hoặc bẫy lỗi.
3. Hầu hết các CSDL quan trọng không cho phép truy vấn bằng lệnh SQL suông. Gọi SQL sẽ dẫn đến việc phá hoại (SQL attack). Cách duy nhất mà admin cho phép là gọi thủ tục (stored procedure) và chi tiết thì được nạp qua tham số. Trong trường hợp này, cái object connection tường minh nó giúp bạn làm việc dễ hơn.

(*) cũng giống như biến, bạn không bắt buộc phải khai báo. Bạn hoàn toàn có thể để dùng đến đâu VBA tự lập biến đến đó.
Lý do bạn khai báo biến là vì muốn kiểm soát cho dễ. Lý do code của bạn không cần dựng connection tường minh là vì giai đoạn sử dụng rất ngắn, trung bình khoảng chục dòng code.
 
Khi mở một file để đọc, ADO coi như đó là một CSDL, và nó cần tạo một connection để kết nối. Cái lệnh Open mà bạn thấy nó chính thức gồm luôn Open Connection và Excute Command (lệnh SQL).
Khi chỉ cần đọc một lần, cái connection có thể được hiểu ngầm (implicit, trái với tường minh là explicit), đọc xong rồi bỏ. Kiểu giống như sử dụng các đối tượng bằng lệnh With CreateObject(...) - End With, cái Object đó được thành lập và bỏ sau lệnh End With.
Lý do tại sao phải mở connection tường minh (khai báo và set 1 cái object connection):
1. Khi cần đọc nhiều lần: một lần connect vào CSDL tốn tài nguyên, vì vậy nếu đọc nhiều lần thì nên giữ lại. Sau khi đọc xong thì đóng lại (huỷ đi). Hầu hết công việc mà các bạn làm ở đây chỉ đọc mỗi file 1 lần cho nên bạn chưa thấy nhu cầu này.
2. Khi CSDL thuộc loại có nhiều thủ tục (ví dụ SQL Server có admin của nó, chỉ cho phép 1 số tình trạng kết nối). Ngừoi dùng cần phân biệt lúc kết nối và lúc lấy dữ liệu để có thể debug hoặc bẫy lỗi.
3. Hầu hết các CSDL quan trọng không cho phép truy vấn bằng lệnh SQL suông. Gọi SQL sẽ dẫn đến việc phá hoại (SQL attack). Cách duy nhất mà admin cho phép là gọi thủ tục (stored procedure) và chi tiết thì được nạp qua tham số. Trong trường hợp này, cái object connection tường minh nó giúp bạn làm việc dễ hơn.

(*) cũng giống như biến, bạn không bắt buộc phải khai báo. Bạn hoàn toàn có thể để dùng đến đâu VBA tự lập biến đến đó.
Lý do bạn khai báo biến là vì muốn kiểm soát cho dễ. Lý do code của bạn không cần dựng connection tường minh là vì giai đoạn sử dụng rất ngắn, trung bình khoảng chục dòng code.
Cảm ơn Bạn ... tại vì chưa hiểu sâu xa bản chất của vấn đề nên mới hỏi để học tập nghiên cứu thêm ... vậy là phần nào hiểu chút chút :p:D
 
Cảm ơn Bạn ... tại vì chưa hiểu sâu xa bản chất của vấn đề nên mới hỏi để học tập nghiên cứu thêm ... vậy là phần nào hiểu chút chút :p:D
Nói nôm na như thế này. Khi anh cần nhập, xuất hàng thì anh phải mở của kho để nhập xuất, nếu trong phiên làm việc có nhiều lần nhập xuất và việc nhập xuất đó liên tục thì anh vẫn phải để cửa kho cho người ta nhập xuất. Khi hết phiên làm việc mới đóng cửa kho, không phải khi vừa nhập hoặc vừa xuất xong thì đóng cửa kho và mở cửa kho liên tục, làm như vậy vẫn được nhưng hãy suy nghĩ lại có ổn không. Tương tự trong ứng dụng liên quan đến CSDL người ta thường khai báo và mở kết nối 1 lần (Mở cửa kho), sau đó thực hiện thêm, xóa, lấy, chỉnh sửa... (Nhập xuất hàng). Khi kết thúc ứng dụng thì đóng kết nối (Đóng cửa kho). Dĩ nhiên phải lưu ý việc ứng dụng đã chạy nhưng không dùng thì ta phải đặt thời gian thích hợp ở Server hoăc ở ứng dụng để hủy kết nối nhằm giảm tải cho Server.
 
Nói nôm na như thế này. Khi anh cần nhập, xuất hàng thì anh phải mở của kho để nhập xuất, nếu trong phiên làm việc có nhiều lần nhập xuất và việc nhập xuất đó liên tục thì anh vẫn phải để cửa kho cho người ta nhập xuất. Khi hết phiên làm việc mới đóng cửa kho, không phải khi vừa nhập hoặc vừa xuất xong thì đóng cửa kho và mở cửa kho liên tục, làm như vậy vẫn được nhưng hãy suy nghĩ lại có ổn không. Tương tự trong ứng dụng liên quan đến CSDL người ta thường khai báo và mở kết nối 1 lần (Mở cửa kho), sau đó thực hiện thêm, xóa, lấy, chỉnh sửa... (Nhập xuất hàng). Khi kết thúc ứng dụng thì đóng kết nối (Đóng cửa kho). Dĩ nhiên phải lưu ý việc ứng dụng đã chạy nhưng không dùng thì ta phải đặt thời gian thích hợp ở Server hoăc ở ứng dụng để hủy kết nối nhằm giảm tải cho Server.
Mạnh hiểu rồi vậy nên nó mới đẻ ra cái dòng sau phải ko ?!
Mã:
If Cnn.State <> 1 Then
 
Chính xác vậy và đây là code Mạnh Viết .. Nhờ HLMT coi dùm
Mã:
Private Sub CopyRecordset()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Cells.ClearContents
        Range("A1").CopyFromRecordset Rst
    End If
End Sub
Rem ==========
Private Sub GetDataGetRows()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    Dim dArr(), Arr(), i As Long, j As Long, k As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Arr = Rst.getrows(RecCount)
        ReDim dArr(1 To UBound(Arr, 2) + 1, 1 To UBound(Arr, 1) + 1)
        For i = 0 To UBound(Arr, 2)
            k = k + 1
            For j = 0 To UBound(Arr, 1)
                dArr(k, j + 1) = Arr(j, i)
            Next j
        Next i
        Cells.ClearContents
        Range("A2").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
    End If
End Sub
bạn có thể cho mình xin file đính kèm dùng code này hoạt động để học hỏi thêm được không ạ.
 
Chính xác vậy và đây là code Mạnh Viết .. Nhờ HLMT coi dùm
Mã:
Private Sub CopyRecordset()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Cells.ClearContents
        Range("A1").CopyFromRecordset Rst
    End If
End Sub
Rem ==========
Private Sub GetDataGetRows()
    Dim Rst As Object, SQL As String
    Dim Strcon As String, ExcelPath As String
    Dim RecCount  As Long
    Dim dArr(), Arr(), i As Long, j As Long, k As Long
    ExcelPath = ThisWorkbook.Path & "\Data.xlsb"
    Set Rst = CreateObject("ADODB.Recordset")
    SQL = "select * from [Data_Nhap$]" ''Tuy chon Mo Rong de lay du lieu
    Strcon = ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
                & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
    Rst.Open SQL, Strcon, 3, 1
    RecCount = Rst.RecordCount
    MsgBox RecCount
    If Not Rst.EOF Then
        Arr = Rst.getrows(RecCount)
        ReDim dArr(1 To UBound(Arr, 2) + 1, 1 To UBound(Arr, 1) + 1)
        For i = 0 To UBound(Arr, 2)
            k = k + 1
            For j = 0 To UBound(Arr, 1)
                dArr(k, j + 1) = Arr(j, i)
            Next j
        Next i
        Cells.ClearContents
        Range("A2").Resize(UBound(dArr, 1), UBound(dArr, 2)) = dArr
    End If
End Sub




Em cảm ơn anh kiều mạnh nhiều ạ
Cảm ơn anh về cái code trên ^^
 
Câu trả lời của Mình là ĐƯỢC .... TA không cần sử dụng connection hay chi tiết như sau ta vẫn có thể lấy dữ liệu lên Sheet hay mảng ok
Mã:
Set cn = CreateObject("ADODB.Connection")
Ta chỉ cần cơ bản 1 dòng sau là đủ để lấy dữ liệu lên Sheet hay lên Mảng
Mã:
Set rst = CreateObject("ADODB.Recordset")
Làm phiền @Hai Lúa Miền Tây cho xin 1 ý kiến cho bài 321 & 322 và bài này ... Mạnh Cảm Ơn
Xin nói thêm là nếu như ta dùng trên cùng 1 file thì không cần phải mở kết nối hay khai báo chuỗi kết nối.
Vậy phương pháp để lấy dữ liệu bằng cách này là như thế nào. Mời các bạn cho ý kiến nhé.
 
Tôn chỉ ở diễn đàn này là code ngắn và nhanh. Luật code rõ ràng, dễ kiểm soát lỗi là điều thứ yếu.
Với tôn chỉ ấy thì phương pháp "implicit connection" (để cho recordset nó tự kết nối lấy "đằng sau hậu trường") là phương pháp lý tưởng.
Hết.
 
Lần chỉnh sửa cuối:
Tôn chỉ ở diễn đàn này là code ngắn và nhanh. Luật code rõ ràng, dễ kiểm soát lỗi là điều thứ yếu.
Với tôn chỉ ấy thì phương pháp "implicit connection" (để cho recordset nó tự kết nối lấy "đằng sau hậu trường") là phương pháp lý tưởng.
Hết.
Không dùng kết nối nhé anh, code chưa chắc là ngắn gọn. Nhưng tốc độ thì hơn hẳn so với cách thông thường. Ở máy cà tàng của em thì với dữ liệu 1.048.576 dòng thì nó cho ra kết quả trong vòng 15~20 giây. Trong khi đó với cách mở kết nối thì hơn 80 giây mới có kết quả.
 
Implicit (đằng sau lưng) !
ADO tự thương lượng và hiệu chỉnh (negotiate, configure) các lệ ước (protocol) với nơi nó muốn kết nối. Nhanh hay chậm là do nó có thể negotiate như thế nào. Nhưng vì hai bên tự thoả thuận với nhau cách "gọn gàng và ít tốn năng lượng nhất" cho nên code VBA không có quyền hạn gì ở đây cả. Recordset nó đưa kết quả về thì lấy, nó không đưa thì ráng chịu.
Cách kết nối explicit (caller làm chủ động) có một số commands để làm việc rõ rệt hơn nếu cần. Vì ở đây quý vị chưa cần đến các luật này cho nên chúng chả hề được nhắc tới.
 
Sẵn đang bàn về ADO, anh/ chị cho em hỏi có cách nào để biết được 1 file Excel đang được mở connection. Mục đích là chờ file Excel đó close kết nối đó rồi mới tạo connection, vì nếu open connection đến một file Excel đang open connection khác thì chương trình Excel sẽ mở file đó ở chế độ ReadOnly. Cảm ơn anh/ chị!
 
Xin nói thêm là nếu như ta dùng trên cùng 1 file thì không cần phải mở kết nối hay khai báo chuỗi kết nối.
Vậy phương pháp để lấy dữ liệu bằng cách này là như thế nào. Mời các bạn cho ý kiến nhé.
quay lại bài này 1 chút
Trường hợp mạnh không xài 2 công cụ sau + ko xài hàm của Excel + Macro4 mà vẫn lấy được dữ liệu của File đóng thì ko biết có phải cái mà HLMT hỏi ko nhỉ ... bỏ 2 dòng sau
Mã:
Set cn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
Bỏ hết 2 Tools trên chỉ xài sơ bộ dòng sau ...:bounce:===\.-0-0-0-
Mã:
sConn = "Provider=Microsoft.ACE.OLEDB.12.0 + abczyx(Linh Tinh)
Trong khi vô tình quậy code tầm bạy .... Bác Bill báo theo hình
ADo.PNG
 
Lần chỉnh sửa cuối:
Anh kiem tra duong dan,
quay lại bài này 1 chút
Trường hợp mạnh không xài 2 công cụ sau + ko xài hàm của Excel + Macro4 mà vẫn lấy được dữ liệu của File đóng thì ko biết có phải cái mà HLMT hỏi ko nhỉ ... bỏ 2 dòng sau
Mã:
Set cn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
Bỏ hết 2 Tools trên chỉ xài sơ bộ dòng sau ...:bounce:===\.-0-0-0-
Mã:
sConn = "Provider=Microsoft.ACE.OLEDB.12.0 + abczyx(Linh Tinh)
Trong khi vô tình quậy code tầm bạy .... Bác Bill báo theo hình
View attachment 211057
Anh kiem tra duong dan, cau trùc sql va file ket nói la excel hay accdb. Nó hiện len trên kia
 
quay lại bài này 1 chút
Trường hợp mạnh không xài 2 công cụ sau + ko xài hàm của Excel + Macro4 mà vẫn lấy được dữ liệu của File đóng thì ko biết có phải cái mà HLMT hỏi ko nhỉ ... bỏ 2 dòng sau
Mã:
Set cn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
Bỏ hết 2 Tools trên chỉ xài sơ bộ dòng sau ...:bounce:===\.-0-0-0-
Mã:
sConn = "Provider=Microsoft.ACE.OLEDB.12.0 + abczyx(Linh Tinh)
Trong khi vô tình quậy code tầm bạy .... Bác Bill báo theo hình
View attachment 211057
Có nghĩa là trên cùng 1 file ta không cần khởi tạo kết nối
 
Các Bạn cho Mình hỏi một chút
1/ Thông thường Mình thấy trên GPE thấy đa số mở kết nối ADO theo cách sau
Mã:
Cnn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ExcelPath _
            & ";Extended Properties=""Excel 12.0 Xml;HDR=Yes;"";")
2/ Vậy Mình thử mở kết nối ADO khác đi một tẹo như sau:
Mã:
Cnn.Open "ODBC;DSN=Excel Files;" _
        & "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
        & "DBQ=" & ExcelPath & ";ReadOnly=0;"
Mình thấy 2 cách trên điều chạy tốt
Vấn đề mình muốn hỏi ở đây là :

1/ 2 cách trên nó có điểm gì khác nhau và xài nó trong trường hợp nào là tốt nhất ???

2/ cách thứ 2 có chạy trên tất cả các WindowsXP To Windows10 hay không ... hay phải cài thêm cái gì nữa ???

Rất mong sự giải đáp của các Bạn để Mạnh hiểu thêm một chút về ADO !!!
 
1. thử trên 64 bit
2. thử trên 80000 dòng
So sánh kết quả
 
1. thử trên 64 bit
2. thử trên 80000 dòng
So sánh kết quả
1/ Mình có 4 máy điều xài Windows10_x64 + Office2016_x32 thấy chạy tốt

2/ Ko có máy nào cài Officex64 cả nên cũng ko có mà thử vậy cũng ko biết luôn

3/ Mình cũng ko biết được cụ thể chi tiết là sao nữa .... ko biết nó có chạy nhanh hơn cái mục số 1 hay ko ???!!!

4/ suy đoán là khả năng nhiều hạn chế nên thấy Ít bạn xài mục số 2
 
Lần chỉnh sửa cuối:
Tóc đọ là cái tôi xét đến cuói cùng. Cái này nhanh hớn cái kia 1 chút đói với tôi gần như khong quan trọng. Làm việc với CSDL thì tôi chỉ quan tâm việc truy xuất có dễ dàng và chính xác?
Bạn chưa trả lời tôi về việc giới hạn số dòng.
 
Đã từng dùng cách này, tuy nhiên anh hãy test với dữ liệu là Tiếng Việt có dấu (Unicode) nhé.
Thử khai báo lấy nguyên Sheet thấy nó chạy cũng nhanh
Mã:
SQL = "SELECT * FROM [Persons$]"
Hình như dữ liệu thiếu thì phải .... vậy nên thấy ít người xài tới nó :p
 
Nghiên cứu là ngu như kiến, hihi, anh vietmini là tiếp kiem lời nhat, dọc comment của anh em phải nghiệm 1 thời gian mới ra hichic
 
Tóc đọ là cái tôi xét đến cuói cùng. Cái này nhanh hớn cái kia 1 chút đói với tôi gần như khong quan trọng. Làm việc với CSDL thì tôi chỉ quan tâm việc truy xuất có dễ dàng và chính xác?
Bạn chưa trả lời tôi về việc giới hạn số dòng.
Cảm Ơn bạn thôi chạy mất dép cái kiểu kết nối đó thôi HLMT nói đúng thử với Unicode xem sao
Thấy nó lỗi Font
Capture.PNG
 
Các anh chị cho em hỏi xíu
Trong query co cách nào mình xác dinh fiels nào là khóa chính trong câu lệnh sql không ah
 
nếu được thì cả 2 anh hihi
SQLServer thì bạn thử như sau:

Mã:
select schema_name(tab.schema_id) as [schema_name],
    pk.[name] as pk_name,
    ic.index_column_id as column_id,
    col.[name] as column_name,
    tab.[name] as table_name
from sys.tables tab
    inner join sys.indexes pk
        on tab.object_id = pk.object_id
        and pk.is_primary_key = 1
    inner join sys.index_columns ic
        on ic.object_id = pk.object_id
        and ic.index_id = pk.index_id
    inner join sys.columns col
        on pk.object_id = col.object_id
        and col.column_id = ic.column_id
order by schema_name(tab.schema_id),
    pk.[name],
    ic.index_column_id

Bạn phải truy vấn bảng nào đó bạn cần. Ở trên là nó sẽ liệt kê tất cả các bảng có trong CSDL

Còn ở Access thì bạn có thể tham khảo Bài này
 
Cám ơn các anh/chị , Topic rất hay ạ
 
Lần chỉnh sửa cuối:
File text thôi bà con, cứ notepad mà phang :)
 
Lần chỉnh sửa cuối:
File này dùng Notepad.exe là mở được rồi.
Nếu muốn dùng code thì bạn dùng FSO (File System Object)
 
Hì hì, wow cái gì mà wow @appl . Parse file text này có phần mềm chuyên dùng của NH. Chứ bạn code dùng FSO, readall rồi parse nổi không ?
Liên quan đến tiền bạc nữa, parse sai 1 byte thôi cũng đủ tiêu :)
 
Lâu lắm ko vào đây nay đố vui 1 tẹo

1/ File sau nếu mắt thường nhìn nó thì chỉ có 83 dòng hay chọn nguyên cột B thì Count cũng chỉ có 83 dòng ??!!
2/ trên thực tế thì nó có tới 271 RecordCount ( nếu xài ADO mà đếm)
3/ chênh lệch nhau là: 271 - 83 = 188 RecordCount

Vậy muốn đố là:

1/ sự chênh lệch nhau 188 đó ở đâu ra mà có ... tại sao ???!!!
2/ Cách xử lý nó ??? ... có mấy cách ??!!!
3/ đó là 1 trong những nguyên nhân làm File Excel phình to ra theo thời gian mặc dù dữ liệu có 1 tẹo
.....
đó cũng là 1 cái gì đó giúp ai đó đang và sẻ xài ADO hiểu thêm nó 1 chút :D

Untitled.png
 

File đính kèm

Lâu lắm ko vào đây nay đố vui 1 tẹo

1/ File sau nếu mắt thường nhìn nó thì chỉ có 83 dòng hay chọn nguyên cột B thì Count cũng chỉ có 83 dòng ??!!
2/ trên thực tế thì nó có tới 271 RecordCount ( nếu xài ADO mà đếm)
3/ chênh lệch nhau là: 271 - 83 = 188 RecordCount

Vậy muốn đố là:

1/ sự chênh lệch nhau 188 đó ở đâu ra mà có ... tại sao ???!!!
2/ Cách xử lý nó ??? ... có mấy cách ??!!!
3/ đó là 1 trong những nguyên nhân làm File Excel phình to ra theo thời gian mặc dù dữ liệu có 1 tẹo
.....
đó cũng là 1 cái gì đó giúp ai đó đang và sẻ xài ADO hiểu thêm nó 1 chút :D

:D bác đố hay là bác hỏi vậy?
- Đối với ADO và theo như file mẫu thì lỗi này do một nguyên nhân và nhớ có lần tôi đề cập rồi.
- Xử lý thì tôi cũng biết 2, 3 cách.
- Cái ý số 3 tôi không nghĩ nó làm phìn file Excel lên đâu.
Thôi đố thì từ từ giải đố vậy. :D
 
:D bác đố hay là bác hỏi vậy?
- Đối với ADO và theo như file mẫu thì lỗi này do một nguyên nhân và nhớ có lần tôi đề cập rồi.
- Xử lý thì tôi cũng biết 2, 3 cách.
- Cái ý số 3 tôi không nghĩ nó làm phìn file Excel lên đâu.
Thôi đố thì từ từ giải đố vậy. :D
cái ý số 3 là có đấy ( nếu nó lên 1048576 ... thì mới thấy ) ... đố chứ ko hỏi he
 
Lâu lắm ko vào đây nay đố vui 1 tẹo

1/ File sau nếu mắt thường nhìn nó thì chỉ có 83 dòng hay chọn nguyên cột B thì Count cũng chỉ có 83 dòng ??!!
2/ trên thực tế thì nó có tới 271 RecordCount ( nếu xài ADO mà đếm)
3/ chênh lệch nhau là: 271 - 83 = 188 RecordCount

Vậy muốn đố là:

1/ sự chênh lệch nhau 188 đó ở đâu ra mà có ... tại sao ???!!!
2/ Cách xử lý nó ??? ... có mấy cách ??!!!
3/ đó là 1 trong những nguyên nhân làm File Excel phình to ra theo thời gian mặc dù dữ liệu có 1 tẹo
.....
đó cũng là 1 cái gì đó giúp ai đó đang và sẻ xài ADO hiểu thêm nó 1 chút :D

View attachment 241246
Do trong bảng tính có định dạng (Cột I) đến dòng 271. Nếu bảng dữ liệu có định dạng hoặc dòng đã được nhập dữ liệu cho dù đã xóa bằng phím Delete trên bàn phím thì nó vẫn tính là có dữ liệu.
Cách khắc phục đơn giản là xuống cuối bảng dòng số 86 nhấn tổ hợp phím Shift+Phím cách trắng >> Shift+Ctrl+Mũi tên xuống >> Ctrl+dấu trừ
 
Lâu quá không trở lại đề tài này, hôm nay mình xin đố các bạn là làm sao lấy được danh sách tên cột của một bảng cho trước mà không dùng vòng lặp?
Trong file mẫu tôi gửi có 3 sheets (Sheet1, Sheet2, Sheet3), và 1 sheet KetQua. Khi tôi muốn lấy tên cột của sheet nào thì nó lấy kết quả tên cột của sheet ấy.

1595475137926.png
 

File đính kèm

Lâu quá không trở lại đề tài này, hôm nay mình xin đố các bạn là làm sao lấy được danh sách tên cột của một bảng cho trước mà không dùng vòng lặp?
Trong file mẫu tôi gửi có 3 sheets (Sheet1, Sheet2, Sheet3), và 1 sheet KetQua. Khi tôi muốn lấy tên cột của sheet nào thì nó lấy kết quả tên cột của sheet ấy.

Tôi sẽ dùng Fields Collection của ADODB recordset.
Lưu xuống Sheet thì dùng hàm Transpose().
 
Mã:
Sub GetFiled_Thuyyeu99()
Dim SheetName As String
Dim cn As Object, rs As Object, arr() As Variant
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
SheetName = InputBox(prompt:="Nhap ten Sheet", Title:="Lay Filed tren Excel", Default:="Sheet1")
If StrPtr(SheetName) = 0 Then Exit Sub
If SheetName = NullString Then Exit Sub
    SheetName = SheetName & "$"
cn.Open _
    "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                "data source=" & ThisWorkbook.FullName & ";" & _
                "extended properties=excel 12.0 macro;"
Set rs = cn.OpenSchema(4, Array(Empty, Empty, SheetName))
arr = rs.GetRows(, , "COLUMN_NAME")
ActiveCell.Resize(UBound(arr, 2) - LBound(arr, 2) + 1, 1).Value = Application.Transpose(arr)
rs.Close
cn.Close
End Sub
 
Mã:
Sub GetFiled_Thuyyeu99()
Dim SheetName As String
Dim cn As Object, rs As Object, arr() As Variant
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
SheetName = InputBox(prompt:="Nhap ten Sheet", Title:="Lay Filed tren Excel", Default:="Sheet1")
If StrPtr(SheetName) = 0 Then Exit Sub
If SheetName = NullString Then Exit Sub
    SheetName = SheetName & "$"
cn.Open _
    "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                "data source=" & ThisWorkbook.FullName & ";" & _
                "extended properties=excel 12.0 macro;"
Set rs = cn.OpenSchema(4, Array(Empty, Empty, SheetName))
arr = rs.GetRows(, , "COLUMN_NAME")
ActiveCell.Resize(UBound(arr, 2) - LBound(arr, 2) + 1, 1).Value = Application.Transpose(arr)
rs.Close
cn.Close
End Sub
Chính xác là chỗ đó, đáp án như sau:

Mã:
Sub ColumnsName_HLMT()
    Dim Arr() As Variant
    With CreateObject("ADODB.Connection")
        .Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ThisWorkbook.FullName + ";Extended Properties=""Excel 12.0"";")
        Arr = .OpenSchema(4, Array(Empty, Empty, "Sheet2$", Empty)).getrows(, , "COLUMN_NAME")
    End With
    ActiveCell.Resize(UBound(Arr, 2) + 1, 1).Value = Application.Transpose(Arr)
End Sub
 
Lâu quá không trở lại đề tài này, hôm nay mình xin đố các bạn là làm sao lấy được danh sách tên cột của một bảng cho trước mà không dùng vòng lặp?
Trong file mẫu tôi gửi có 3 sheets (Sheet1, Sheet2, Sheet3), và 1 sheet KetQua. Khi tôi muốn lấy tên cột của sheet nào thì nó lấy kết quả tên cột của sheet ấy.

View attachment 241663

Không xài chữ to mà xài Application.Transpose
Mạnh đoán là hàm đó Bill cũng chạy 2 dòng For đấy
 
:) Anh cũng dùng ADO OpenSchema nhưng lại không biết chuyển thành array như thế nào... Ai ngờ cái getRows có các tham số như vậy, đúng là chưa khai thác hết nó... hehe.
quậy đi là viết SQL OK đó ... lâu nay Mạnh đang xài nó ... biết vài tháng nay rồi từ trước khi Ông gì hỏi trên GPE lấy SheetName đó
bài số 4 link sau
1595493079874.png
 
Lần chỉnh sửa cuối:
quậy đi là viết SQL OK đó ... lâu nay Mạnh đang xài nó ... biết vài tháng nay rồi từ trước khi Ông gì hỏi trên GPE lấy SheetName đó
bài số 4 link sau
View attachment 241689
Thật ra cái vụ tên sheet và tên cột đã được HLMT đố vui hồi năm 2015, tuy nhiên nó nằm ở đề tài khác, không nằm ở đây nên muốn "đố lại" cho "đủ bộ"

Tên sheet
1595554209827.png
Tên cột

1595554278241.png

 
Thật ra cái vụ tên sheet và tên cột đã được HLMT đố vui hồi năm 2015, tuy nhiên nó nằm ở đề tài khác, không nằm ở đây nên muốn "đố lại" cho "đủ bộ"

Tên sheet
View attachment 241716
Tên cột

View attachment 241717

Trên GPE này có rất nhiều code rất chi là hay ... quan trọng ai đó có biết vận dụng và kết hợp nó lại hay ko đó thôi ...!!!???
kết hợp 2 cái đó lại viết thêm cái hàm nối chuỗi nữa là có 1 cái SQL tùy chọn đấy .... ( Mạnh lấy ý tưởng từ đó )
Hy vọng có cái SQL cho Excel + Access thứ 2 + n xuất hiện trên GPE

Ngay cái Hàm Value kiểu Office 365 trên VBA Mạnh viết OK mà ko có liên quan gì tới khai báo API cả ... Nếu ai đó đam mê kiên trì mò là ra -0-0-0-
 
Thấy mục này đang hay ... Tiếp theo Mạnh đố chứ ko có hỏi nhe
Câu lệnh SQL sau quá dài vậy có câu nào khác thay thế nó mà mục đích y trang vậy mà ngắn nhất hay ko ???
Mã:
sSQL = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES " & _
           "WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='" & Me.cboDatabaseName & "'"
Nếu lấy phần sau rồi đếm nó thì có 98 ký tự ( Len(SQL) )
Mã:
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG
Với câu SQL trên Mạnh viết lại chỉ có 36 ký tự
Xin mời góp vui 1 tí
 
Thấy mục này đang hay ... Tiếp theo Mạnh đố chứ ko có hỏi nhe
Câu lệnh SQL sau quá dài vậy có câu nào khác thay thế nó mà mục đích y trang vậy mà ngắn nhất hay ko ???
Mã:
sSQL = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES " & _
           "WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='" & Me.cboDatabaseName & "'"
Nếu lấy phần sau rồi đếm nó thì có 98 ký tự ( Len(SQL) )
Mã:
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG
Với câu SQL trên Mạnh viết lại chỉ có 36 ký tự
Xin mời góp vui 1 tí
Nó nằm trong cái sys.Tables. Nếu dùng câu lệnh ngắn hơn để lấy danh sách Table thì có thể vào đây lấy.
Mã:
Select name from sys.Tables
 
Anh hơi vui tính, nó không những cho lấy được từ những cái trên mà còn hơn thế nữa. Vì sao thì ai cũng có thể hiểu.
Vì ngày qua có hỏi thớt bên kia cái chuỗi đó sao trên Delphi nó Ứ có chạy ... mò diết tối qua mới biết...
vậy là cái chuỗi đó là ok nhất chạy chung cho tất cả đó
 
Vì ngày qua có hỏi thớt bên kia cái chuỗi đó sao trên Delphi nó Ứ có chạy ... mò diết tối qua mới biết...
vậy là cái chuỗi đó là ok nhất chạy chung cho tất cả đó

Vụ này ngộ à.
Cùng là câu lệnh truy vấn Table hệ thống của SQL Server mà có Table cho lấy dữ liệu, có Table không chạy được là sao nhỉ?
Bạn dùng SQL Server phiên bản bao nhiêu?
Mỗi Table hệ thống của SQL SV đều chứa những thông tin riêng của nó, tuỳ nhu cầu, tính tiện dụng mà sử dụng thôi.
Cách ngắn nữa: chạy "Exec sp_tables" :D
 
Lần chỉnh sửa cuối:
Vụ này ngộ à.
Cùng là câu lệnh truy vấn Table hệ thống của SQL Server mà có Table cho lấy dữ liệu, có Table không chạy được là sao nhỉ?
Bạn dùng SQL Server phiên bản bao nhiêu?
Mỗi Table hệ thống của SQL SV đều chứa những thông tin riêng của nó, tuỳ nhu cầu, tính tiện dụng mà sử dụng thôi.
Cách ngắn nữa: chạy "Exec sp_tables" :D
cái này là do Delphi mình khai báo nó chưa có hiễu hay là xài TADOConnection.Create(nil); mà cách khai báo khác nó mới hiểu
Thớt bên kia ngày qua Mạnh có mô tả đó bài 44

Vậy là cái SQL Server Ms trên Delphi của Mạnh có tùy chọn TableName + Cột lấy dữ liệu cơ bản đã xong
-0-0-0-
 

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

Back
Top Bottom