Chuyên mục xử lý, gỡ rối code VBA

Liên hệ QC
Status
Không mở trả lời sau này.

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,918
Excel có cái phần name với hàm Evaluate cũng có thể dùng thay trong trường hợp này, không phải co với cốt làm gì.
 
Upvote 0
Nhưng người ta nói vầy:

Vậy chuyện này là sao?
Em thay đổi thiết lập dấu phân cách trong Control rồi thử hàm ở bài #1540 thì 2 trường hợp: Dấu phân cách phần thập phân là dấu chấm/ Hoặc dấu phẩy thì đều cho kết quả đúng.

Em cũng nhớ mang máng có một anh nói cái này rồi, chờ anh đó vào nhắc lại (có thể em nhớ nhầm).
 
Upvote 0
VBa, hay chính xác hơn là ngôn ngữ VB thì nó tính theo dấu chấm. Còn cái Evaluate nó không phải là vba, nó là thứ người ta viết ra dựa trên vb. Tóm lại là nó tính theo thiết lập của Excel. Tóm lại là anh kiểm tra lại hộ em cái.
Về lý thuyết thì mình chịu rồi, không có kiến thức đó.
 
Upvote 0
Em thay đổi thiết lập dấu phân cách trong Control rồi thử hàm ở bài #1540 thì 2 trường hợp: Dấu phân cách phần thập phân là dấu chấm/ Hoặc dấu phẩy thì đều cho kết quả đúng.

Em cũng nhớ mang máng có một anh nói cái này rồi, chờ anh đó vào nhắc lại (có thể em nhớ nhầm).
Lạ nghen, máy của người ta bị si đa. si đa mà vẫn xông phá đi viết code. anh nhập trực tiếp trong vba xem.
 
Upvote 0
...
Em cũng nhớ mang máng có một anh nói cái này rồi, chờ anh đó vào nhắc lại (có thể em nhớ nhầm).

Có phải bạn nói cái vụ xét MID(3/2, 2,1) để biết máy hiện tại dùng hệ thống nào?

(tôi chỉ nhắc thôi chứ tôi không phải là cái "anh" kia)
 
Upvote 0
Có phải bạn nói cái vụ xét MID(3/2, 2,1) để biết máy hiện tại dùng hệ thống nào?
Em chỉ nhớ láng máng được nội dung: Trong VBA thì luôn nhận dấu chấm là dấu phân cách phần thập phân, ngoài bảng tính thì cần để ý dấu phân cách đó.

Đây là hình ảnh theo gợi ý của anh.
upload_2018-3-8_23-27-2.png

(Cũng có thể em nhớ nhầm mà) :(
 
Upvote 0
Upvote 0
Bạn thử như thế này xem có được không
Code:
Function TT(Str As String)
Str = Replace(Str, ",", ".")
TT = Evaluate("=" & Str)
End Function


PacificPR, Yesterday at 4:13 PM

Cảm ơn bạn nhiều. Mình dùng ok rồi :D
 
Upvote 0
Mình đang từng bước viết lại code của file quản lý bán hàng mà mình đang sử dụng gặp phải 1 vấn đề rắc rối mà chưa xử lý xong úp bài nhờ các Bạn xử lý dùm
1/ Cùng một vấn đề như nhau mình sử Dụng DAO ghi dữ liệu từ Mảng trên Excel vào Table File Access thì chạy tốt ... Nhưng khi mình sử Dụng ADO để ghi vào thì nó báo lỗi "Data type mismatch in criteria expression" tạm dịch kiểu dữ liệu không phù hợp ....

2/ Mình có vào Tables\View chỉnh lại kiểu dữ liệu các kiểu vẫn không được ...cũng không biết sai cái gì ... code viết sai khúc nào ...???

3/ Code trong File mình làm 2 trường hợp là DAO và ADO ... nhờ các bạn xử lý dùm mình phần ADO nó lỗi không chạy được
xim cảm Ơn
Mã:
Private Cnn As New ADODB.Connection
Private Rst As New ADODB.Recordset
Private AccPath As String, TableName As String
Private SQL As String, MyString As String
Rem ==========
Private Function Connection(ByVal AccPath As String) As ADODB.Connection
    Rem Tools/References - VBAProject/Microsoft ActiveX Data Objects 6.1 Library
    Set Cnn = New ADODB.Connection
    Cnn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=") _
        & AccPath & ";Persist Security Info=False"
    Set Connection = Cnn
End Function
Rem ==========
Private Sub CopyTableName(ByVal AccPath As String, ByVal TableName As String, ByVal Target As Range)
    Target.CopyFromRecordset Connection(AccPath).Execute(TableName)
End Sub
Rem ==========
Private Sub InsertQuery(ByVal Cnn As ADODB.Connection, ByVal TableName$, sArr(), _
                       Optional ByVal ColFilter = "", Optional ByVal DelTableName As Boolean = False)
    Dim i As Long, j As Long, Qry As String
    Set Rst = New ADODB.Recordset
    If ColFilter = "" Then ColFilter = 1
    If ColFilter = 0 Or ColFilter > UBound(sArr, 2) Then Exit Sub
'    On Error GoTo Errorhandler          ''Xu Ly loi khi mang Lon Hon tableName Or vv...
    Rem Set Cnn = Connection(AccPath)    ''Bo Tham So Cnn ap dung cho Chay Nhieu Sub truyen 1 Lan Tham So Cnn
    If DelTableName Then Cnn.Execute ("DELETE * FROM ") & TableName
    For i = 1 To UBound(sArr, 1)
        Qry = " INSERT INTO " & TableName & " VALUES(" & i
        If sArr(i, ColFilter) <> "" Then
            For j = 1 To UBound(sArr, 2)
                Qry = Qry & ", " & GetValue(sArr(i, j))
            Next
            Qry = Qry & " )"
            Rst.Open Qry, Cnn, adOpenStatic, adLockOptimistic
        End If
    Next
    Cnn.Close: Set Cnn = Nothing
'    Exit Sub
'Errorhandler:
'    MsgBox "Error #: " & Err.Number _
'        & vbCrLf & Err.Description
'    Rem Range("B1").Value = Err.Number & Err.Description            ''Search Google For Err
    Err.Clear
End Sub
Rem ==========
Public Sub Main_ADO()
    Dim Arr()
    TableName = "NhapXuatTon"
    AccPath = ThisWorkbook.Path & "\QLBHPN.accdb"
    Set Cnn = Connection(AccPath)
    Arr = Range("B4:I100").Value
    ''Call InsertQuery(Cnn, TableName, Arr(), 1, False)
    Call InsertQuery(Cnn, TableName, Arr(), 1, True)
    Sheet4.Range("K4:S1000").ClearContents
    Call CopyTableName(AccPath, TableName, Sheet4.Range("K4"))
End Sub

[code]
 

File đính kèm

  • QLBHPN.rar
    55.8 KB · Đọc: 9
Upvote 0
Không rõ nhập trực tiếp như này phải không? (Thiết lập control, dấu phân cách phần thập phân là dấu phẩy).

View attachment 192302
Converts a Microsoft Excel name to an object or a value.

Syntax

expression.Evaluate(Name)

expression A variable that represents an Application object.

Parameters

Name Required/Optional Data Type Description
Name Required Variant The name of the object, using the naming convention of Microsoft Excel.
Return Value
Variant

Remarks

The following types of names in Microsoft Excel can be used with this method:

  • A1-style references. You can use any reference to a single cell in A1-style notation. All references are considered to be absolute references.
  • Ranges. You can use the range, intersect, and union operators (colon, space, and comma, respectively) with references.
  • Defined names. You can specify any name in the language of the macro.
  • External references. You can use the ! operator to refer to a cell or to a name defined in another workbook — for example, Evaluate("[BOOK1.XLS]Sheet1!A1").
  • Chart Objects. You can specify any chart object name, such as "Legend", "Plot Area", or "Series 1", to access the properties and methods of that object. For example, Charts("Chart1").Evaluate("Legend").Font.Name returns the name of the font used in the legend.

Em đã thử thì nó chạy theo kiểu của người Mỹ, tức là dấu chấm sẽ luôn được hiểu là dấu phân cách phần nghìn.
HTML:
Sub TinhToan()

    Dim strFormual As String
    Dim vValue As Variant
    Dim strPhanCach As String
    
    strPhanCach = Mid(1.5, 2, 1)
    strFormual = "1,200"
    vValue = Sheet1.Evaluate(strFormual)
    Debug.Print "Gia tri bieu thuc voi dau phan cach """ & strPhanCach & """  la:" & CLng(vValue)
    
End Sub

Nhưng nó lại không chấp nhận dấu phẩy như code trên, sẽ chạy sai.
 
Upvote 0
Em thay đổi thiết lập dấu phân cách trong Control rồi thử hàm ở bài #1540 thì 2 trường hợp: Dấu phân cách phần thập phân là dấu chấm/ Hoặc dấu phẩy thì đều cho kết quả đúng.

Em cũng nhớ mang máng có một anh nói cái này rồi, chờ anh đó vào nhắc lại (có thể em nhớ nhầm).
Cụ thể là thế này:
1. Ở ngoài trang tính thì dùng thiết lập trong "Use system separators". Mặc định thì là dùng thiết lập của system. Tức nếu system thiết lập dấu phẩy là dấu thập phân và "Use ..." để mặc định thì khi nhập vào A1 = 2,1 thi đó là số, còn nếu nhập vào A1 = 2.1 thì đó là chuỗi. Nếu system vẫn thiết lập dấu phẩy là dấu thập phân và "Use ..." chuyển thành dấu chấm là dấu thập phân thì khi nhập vào A1 = 2,1 thi đó là chuỗi, còn nếu nhập vào A1 = 2.1 thì đó là số.

2. Dù thiết lập "Use ..." mặc định hay thay đổi thì giá trị số (chỉ giá trị số thôi vì chuỗi thì luôn truyền y nguyên) truyền vào các code VBA luôn lấy thiết lập của system. Tức nếu system thiết lập dấu phẩy là dấu thập phân và "Use ..." để mặc định, tức dấu phẩy là dấu thập phân, thì với A1 = 2,1 giá trị truyền vào code là 2,1. Nếu thiết lập system vẫn thế nhưng người ta đổi "Use ..." thành: dấu chấm là dấu thập phân thì trên trang tính A = 2.1 là số, nhưng giá trị truyền vào code là 2,1 - lấy thiết lập của system.

3. Hàm Evaluate luôn luôn dùng dấu chấm là dấu thập phân. Nếu giá trị đưa vào chứa dấu chấm thì hàm Evaluate coi là số và tính toán. Nếu giá trị đưa vào chứa dấu phẩy thì hàm coi như là chuỗi và không tính toán được nên có lỗi.

Tại sao người hỏi nhìn thấy 2.1 là số mà lại có lỗi?
Do người ta không đưa tập tin nên tôi chỉ đoán mò là họ có thiết lập trong system dấu phẩy là dấu thập phân nhưng họ đã sửa mặc định "Use ..." thành dấu thập phân là dấu chấm. Lúc này A1 = 2.1 là số (điểm 1) nhưng giá trị truyền vào code là 2,1 (lấy thiết lập của system - điểm 2). Evaluate chỉ chấp nhận dấu chấm là dấu thập phân nên sẽ có lỗi.

Em thay đổi thiết lập dấu phân cách trong Control rồi thử hàm ở bài #1540 thì 2 trường hợp: Dấu phân cách phần thập phân là dấu chấm/ Hoặc dấu phẩy thì đều cho kết quả đúng.
Bởi bạn không thay đổi mặc định "Use ..." như người ta.
A. Bạn thiết lập trong system dấu chấm là dấu thập phân.
Lúc này nếu bạn nhập A1 = 2.1 thì đó là số. Giá trị truyền vào code cũng là 2.1 vì lấy theo thiết lập của system - điểm 2. Evaluate coi 2.1 là số - điểm 3, nên không có lỗi.
B. Bạn thiết lập trong system dấu phẩy là dấu thập phân.
Lúc này nếu bạn nhập A1 = 2.1 thì đó là chuỗi. Giá trị truyền vào code cũng là 2.1 vì đó là chuỗi chứ không là số. Evaluate coi 2.1 là số - điểm 3, nên không có lỗi

Nếu bây giờ vẫn thiết lập như điểm B nhưng bạn nhập A1 = 2,1 thì rõ ràng nó là số. Giá trị truyền vào code cũng là 2,1 vì lấy theo thiết lập của system - điểm 2. Nhưng Evaluate không coi 2,1 là số - điểm 3, nên sẽ có lỗi. Bạn thử sẽ thấy.

Do Evaluate chỉ chấp nhận dấu chấm (điểm 3) nên code của PacificPR luôn chuyển dấu phẩy nếu có thành dấu chấm.
 
Upvote 0
Cụ thể là thế này:
1. Ở ngoài trang tính thì dùng thiết lập trong "Use system separators". Mặc định thì là dùng thiết lập của system. Tức nếu system thiết lập dấu phẩy là dấu thập phân và "Use ..." để mặc định thì khi nhập vào A1 = 2,1 thi đó là số, còn nếu nhập vào A1 = 2.1 thì đó là chuỗi. Nếu system vẫn thiết lập dấu phẩy là dấu thập phân và "Use ..." chuyển thành dấu chấm là dấu thập phân thì khi nhập vào A1 = 2,1 thi đó là chuỗi, còn nếu nhập vào A1 = 2.1 thì đó là số.

2. Dù thiết lập "Use ..." mặc định hay thay đổi thì giá trị số (chỉ giá trị số thôi vì chuỗi thì luôn truyền y nguyên) truyền vào các code VBA luôn lấy thiết lập của system. Tức nếu system thiết lập dấu phẩy là dấu thập phân và "Use ..." để mặc định, tức dấu phẩy là dấu thập phân, thì với A1 = 2,1 giá trị truyền vào code là 2,1. Nếu thiết lập system vẫn thế nhưng người ta đổi "Use ..." thành: dấu chấm là dấu thập phân thì trên trang tính A = 2.1 là số, nhưng giá trị truyền vào code là 2,1 - lấy thiết lập của system.

3. Hàm Evaluate luôn luôn dùng dấu chấm là dấu thập phân. Nếu giá trị đưa vào chứa dấu chấm thì hàm Evaluate coi là số và tính toán. Nếu giá trị đưa vào chứa dấu phẩy thì hàm coi như là chuỗi và không tính toán được nên có lỗi.

Tại sao người hỏi nhìn thấy 2.1 là số mà lại có lỗi?
Do người ta không đưa tập tin nên tôi chỉ đoán mò là họ có thiết lập trong system dấu phẩy là dấu thập phân nhưng họ đã sửa mặc định "Use ..." thành dấu thập phân là dấu chấm. Lúc này A1 = 2.1 là số (điểm 1) nhưng giá trị truyền vào code là 2,1 (lấy thiết lập của system - điểm 2). Evaluate chỉ chấp nhận dấu chấm là dấu thập phân nên sẽ có lỗi.


Bởi bạn không thay đổi mặc định "Use ..." như người ta.
A. Bạn thiết lập trong system dấu chấm là dấu thập phân.
Lúc này nếu bạn nhập A1 = 2.1 thì đó là số. Giá trị truyền vào code cũng là 2.1 vì lấy theo thiết lập của system - điểm 2. Evaluate coi 2.1 là số - điểm 3, nên không có lỗi.
B. Bạn thiết lập trong system dấu phẩy là dấu thập phân.
Lúc này nếu bạn nhập A1 = 2.1 thì đó là chuỗi. Giá trị truyền vào code cũng là 2.1 vì đó là chuỗi chứ không là số. Evaluate coi 2.1 là số - điểm 3, nên không có lỗi

Nếu bây giờ vẫn thiết lập như điểm B nhưng bạn nhập A1 = 2,1 thì rõ ràng nó là số. Giá trị truyền vào code cũng là 2,1 vì lấy theo thiết lập của system - điểm 2. Nhưng Evaluate không coi 2,1 là số - điểm 3, nên sẽ có lỗi. Bạn thử sẽ thấy.

Do Evaluate chỉ chấp nhận dấu chấm (điểm 3) nên code của PacificPR luôn chuyển dấu phẩy nếu có thành dấu chấm.
Vâng anh. Cảm ơn anh nhiều.
Nội dung em "nhớ mang máng" chính là điểm số 3 đó. :)

Chúc anh chiều - tối vui!
 
Upvote 0
Mình đang từng bước viết lại code của file quản lý bán hàng mà mình đang sử dụng gặp phải 1 vấn đề rắc rối mà chưa xử lý xong úp bài nhờ các Bạn xử lý dùm
1/ Cùng một vấn đề như nhau mình sử Dụng DAO ghi dữ liệu từ Mảng trên Excel vào Table File Access thì chạy tốt ... Nhưng khi mình sử Dụng ADO để ghi vào thì nó báo lỗi "Data type mismatch in criteria expression" tạm dịch kiểu dữ liệu không phù hợp ....

2/ Mình có vào Tables\View chỉnh lại kiểu dữ liệu các kiểu vẫn không được ...cũng không biết sai cái gì ... code viết sai khúc nào ...???

3/ Code trong File mình làm 2 trường hợp là DAO và ADO ... nhờ các bạn xử lý dùm mình phần ADO nó lỗi không chạy được
xim cảm Ơn
Mã:
Private Cnn As New ADODB.Connection
Private Rst As New ADODB.Recordset
Private AccPath As String, TableName As String
Private SQL As String, MyString As String
Rem ==========
Private Function Connection(ByVal AccPath As String) As ADODB.Connection
    Rem Tools/References - VBAProject/Microsoft ActiveX Data Objects 6.1 Library
    Set Cnn = New ADODB.Connection
    Cnn.Open ("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=") _
        & AccPath & ";Persist Security Info=False"
    Set Connection = Cnn
End Function
Rem ==========
Private Sub CopyTableName(ByVal AccPath As String, ByVal TableName As String, ByVal Target As Range)
    Target.CopyFromRecordset Connection(AccPath).Execute(TableName)
End Sub
Rem ==========
Private Sub InsertQuery(ByVal Cnn As ADODB.Connection, ByVal TableName$, sArr(), _
                       Optional ByVal ColFilter = "", Optional ByVal DelTableName As Boolean = False)
    Dim i As Long, j As Long, Qry As String
    Set Rst = New ADODB.Recordset
    If ColFilter = "" Then ColFilter = 1
    If ColFilter = 0 Or ColFilter > UBound(sArr, 2) Then Exit Sub
'    On Error GoTo Errorhandler          ''Xu Ly loi khi mang Lon Hon tableName Or vv...
    Rem Set Cnn = Connection(AccPath)    ''Bo Tham So Cnn ap dung cho Chay Nhieu Sub truyen 1 Lan Tham So Cnn
    If DelTableName Then Cnn.Execute ("DELETE * FROM ") & TableName
    For i = 1 To UBound(sArr, 1)
        Qry = " INSERT INTO " & TableName & " VALUES(" & i
        If sArr(i, ColFilter) <> "" Then
            For j = 1 To UBound(sArr, 2)
                Qry = Qry & ", " & GetValue(sArr(i, j))
            Next
            Qry = Qry & " )"
            Rst.Open Qry, Cnn, adOpenStatic, adLockOptimistic
        End If
    Next
    Cnn.Close: Set Cnn = Nothing
'    Exit Sub
'Errorhandler:
'    MsgBox "Error #: " & Err.Number _
'        & vbCrLf & Err.Description
'    Rem Range("B1").Value = Err.Number & Err.Description            ''Search Google For Err
    Err.Clear
End Sub
Rem ==========
Public Sub Main_ADO()
    Dim Arr()
    TableName = "NhapXuatTon"
    AccPath = ThisWorkbook.Path & "\QLBHPN.accdb"
    Set Cnn = Connection(AccPath)
    Arr = Range("B4:I100").Value
    ''Call InsertQuery(Cnn, TableName, Arr(), 1, False)
    Call InsertQuery(Cnn, TableName, Arr(), 1, True)
    Sheet4.Range("K4:S1000").ClearContents
    Call CopyTableName(AccPath, TableName, Sheet4.Range("K4"))
End Sub

[code]
Bài này khó quá hay sao mà ko thấy bạn nào giúp mình một tẹo he
 
Upvote 0
Bài #1555 Mạnh tạm thời xử lý xong
1/ Nó báo lỗi kiểu dữ liêu ko phù hợp là do trong mãng có dòng = Empty ...Nhưng mạnh vẫn suy nghĩ tại sao cùng 1 vấn đề đó mà DAO xử lý ok còn ADO báo Lỗi

2/ Nếu ta xét điều kiện trong Mãng mà = Empty thì cho nó = 0 lại OK ...tại sao ?!
If IsEmpty(sArr(x, y)) Then sArr(x, y) = 0

Phải chăng phải có cái gì đó cho nó ghi mới OK còn bỏ trống là lỗi

3/ Nếu ta chạy code đó cho TableName khác mà có Trường dữ liệu Format là Ngay/thang/nam thì nó lại báo lỗi ....Còn DAO thì kiểu gì cũng chơi hết ... Tại SAO ?!

4/ Bạn nào biết chỉ dùm mạnh một chút .... để Mạnh viết 1 cái Hàm InsertQuery Sử dụng ADO có thể xài cho nhiều trường hợp khác nhau như sử dụng DAO

Code sau đã điều chỉnh chạy tốt cho bài #1555
PHP:
Public Sub InsertQuery(ByVal Cnn As ADODB.Connection, ByVal TableName$, sArr(), _
                       Optional ByVal ColFilter = "", Optional ByVal DelTableName As Boolean = False)
    Rem Cu Phap: Call InsertMySQL(Cnn, TableName, Arr(), 1, True)       ''Xoa Du Lieu cu Luu Moi
    Rem Cu Phap: Call InsertMySQL(Cnn, TableName, Arr(), 1, False)      ''Ghi du lieu Moi noi xuong
    Rem ColFilter = 1 Xet Cot trong Mang sArr() Neu co du lieu thi lay
    Dim x As Long, y As Long, Qry As String
    Set Rst = New ADODB.Recordset
    If ColFilter = "" Then ColFilter = 1
    If ColFilter = 0 Or ColFilter > UBound(sArr, 2) Then Exit Sub
    On Error GoTo Errorhandler
    If DelTableName Then Cnn.Execute ("DELETE * FROM ") & TableName
    For x = 1 To UBound(sArr, 1)
        Qry = " INSERT INTO " & TableName & " VALUES(" & x
        If sArr(x, ColFilter) <> "" Then
            For y = 1 To UBound(sArr, 2)
                If IsEmpty(sArr(x, y)) Then sArr(x, y) = 0
                Qry = Qry & ", " & GetValue(sArr(x, y))
            Next
            Qry = Qry & " )"
            Rst.Open Qry, Cnn, 3, 3
        End If
    Next
    Rst.Close: Set Rst = Nothing
    Cnn.Close: Set Cnn = Nothing
    Exit Sub
Errorhandler:
    MsgBox "Error #: " & Err.Number & vbCrLf & Err.Description
    Err.Clear
End Sub

Mong Các Bạn chỉ thêm... Mấy cái tại sao mà ngủ mất ngon :D
Xin cảm ơn
 
Upvote 0
Chào thầy!
em co file đính kèm, e học cachsc viết về array, nhưng e xử lý code trong một Sub, em muốn tạo hàm con khi nhật dong và cột vào ô excel,nhưng bị báo lỗi , mon thầy giúp dum em sai chổ nào
thanks
 

File đính kèm

  • test array.xlsm
    17.9 KB · Đọc: 7
Upvote 0
Chào thầy!
em co file đính kèm, e học cachsc viết về array, nhưng e xử lý code trong một Sub, em muốn tạo hàm con khi nhật dong và cột vào ô excel,nhưng bị báo lỗi , mon thầy giúp dum em sai chổ nào
thanks
Nếu viết hàm thì dùng Function chứ sao lại là Sub, báo lỗi là đúng rồi.
 
Upvote 0
Chào thầy!
em co file đính kèm, e học cachsc viết về array, nhưng e xử lý code trong một Sub, em muốn tạo hàm con khi nhật dong và cột vào ô excel,nhưng bị báo lỗi , mon thầy giúp dum em sai chổ nào
thanks
Bạn viết vầy:
Mã:
RES = GPE(rowa, cola)
là sai cú pháp
Phải vầy mới đúng:
Mã:
GPE rowa, cola
 
Upvote 0
Status
Không mở trả lời sau này.
Web KT
Back
Top Bottom