Nhờ chỉnh sửa code tính tổng sử dụng Macro

Quảng cáo

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0
Dear all
Nhờ mọi người chỉnh sửa giúp mình code tính tổng này với. Code này trước mình xin được của 1 bác trên đây. code ở máy mình thì chạy ra kết quả bình thường không vấn đề ji. nhưng copy file excel sang file khác thì báo lỗi # Value. Mình đang nghĩ là do khác nhau về dấu chấm, dấy phẩy trong Excel của mỗi máy.


Mã:
Function DValue(ByVal Str As String) As Double
Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long, Val As Double
If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
Do
   StartGroup = InStr(StartGroup + 1, Str, "(")
   If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Val = 0
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1), Val) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        Else
            StartGroup = NextStartGroup
        End If
    Else
        CalculateStr Str, DValue
        Exit Function
    End If
Loop
End Function
Mã:
Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
Dim TmpStr As String, ArrStr, i As Long, TmpVal As Double, P1 As String, P2 As String
If Len(Str) < 255 Then
    If Len(Str) > 0 Then
        Val = Evaluate("=" & Str)
        CalculateStr = CStr(Val)
    End If
Else
    If InStr(1, Str, "+") > 0 Then
        ArrStr = Split(Str, "+")
        For i = 0 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), TmpVal
            Val = Val + TmpVal
        Next
    ElseIf InStr(1, Str, "-") > 0 Then
        ArrStr = Split(Str, "-")
        CalculateStr ArrStr(0), Val
        Val = Val + TmpVal
        For i = 1 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), Val
            Val = Val - TmpVal
        Next
    Else
        P1 = InStrRev(Str, "*", 254):   P2 = InStrRev(Str, "/", 254)
        i = IIf(P1 > P2, P1, P1)
        If i = 0 Then
            CalculateStr = " " * " " ' Error
        Else
            TmpVal = Evaluate("=" & Left(Str, i - 1))
            CalculateStr = CalculateStr(CStr(TmpVal) & Mid(Str, i), Val)
        End If
    End If
End If
End Function
 

File đính kèm

  • KL.xls
    120.5 KB · Đọc: 22

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0

buiquangthuan

Thành viên tiêu biểu
Tham gia ngày
17 Tháng mười hai 2010
Bài viết
600
Được thích
239
Điểm
768
Nơi ở
Bắc Ninh
Của mình cũng ra kết quả bình thường. Định dạng trên Excel của máy mình là dấu thấp phân là dấu phẩy "," còn hàng nghìn là dấu chấm "." nhưng 1 số máy đang bị lỗi thì đã chỉnh dấu chấm, dấy phẩy ở trên windowns. Mình đang sợ nó bị lỗi ở đó.
nếu vậy anh thử chỉnh trong phần controlpanel của máy đang bị lỗi coi thế nào
 

snow25

Thành viên gắn bó
Tham gia ngày
24 Tháng bảy 2018
Bài viết
2,768
Được thích
2,736
Điểm
1,368
Của mình cũng ra kết quả bình thường. Định dạng trên Excel của máy mình là dấu thấp phân là dấu phẩy "," còn hàng nghìn là dấu chấm "." nhưng 1 số máy đang bị lỗi thì đã chỉnh dấu chấm, dấy phẩy ở trên windowns. Mình đang sợ nó bị lỗi ở đó.
Nếu ký tự không dài quá 255 ký tự thì thử cái này xem sao.
Mã:
Function aaaa(ByVal dk As String) As Double
    aaaa = Evaluate("=" & dk)
End Function
 

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0
Nếu ký tự không dài quá 255 ký tự thì thử cái này xem sao.
Mã:
Function aaaa(ByVal dk As String) As Double
    aaaa = Evaluate("=" & dk)
End Function
trước mình cũng dùng hàm này rồi. nhưng có những hàng quá 255 ký tự nên mình mới chuyển sang dùng code như vậy.
 

snow25

Thành viên gắn bó
Tham gia ngày
24 Tháng bảy 2018
Bài viết
2,768
Được thích
2,736
Điểm
1,368
trước mình cũng dùng hàm này rồi. nhưng có những hàng quá 255 ký tự nên mình mới chuyển sang dùng code như vậy.
Mình chỉnh 1 chút hàm ở dưới xem đúng không.Mình thấy 2 hàm này nó thế nào ấy.
Mã:
Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
Dim TmpStr As String, ArrStr, i As Long, TmpVal As Double, P1 As String, P2 As String, dk As String
   dk = Replace(Str, ",", ".")
If Len(dk) < 255 Then
    If Len(dk) > 0 Then
        Val = Evaluate("=" & dk)
        CalculateStr = CStr(Val)
    End If
Else
    If InStr(1, dk, "+") > 0 Then
        ArrStr = Split(dk, "+")
        For i = 0 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), TmpVal
            Val = Val + TmpVal
        Next
    ElseIf InStr(1, dk, "-") > 0 Then
        ArrStr = Split(dk, "-")
        CalculateStr ArrStr(0), Val
        Val = Val + TmpVal
        For i = 1 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), Val
            Val = Val - TmpVal
        Next
    Else
        P1 = InStrRev(dk, "*", 254):   P2 = InStrRev(dk, "/", 254)
        i = IIf(P1 > P2, P1, P1)
        If i = 0 Then
            CalculateStr = " " * " " ' Error
        Else
            TmpVal = Evaluate("=" & Left(Str, i - 1))
            CalculateStr = CalculateStr(CStr(TmpVal) & Mid(Str, i), Val)
        End If
    End If
End If
End Function
 

thuyyeu99

Trùm Nhiều Chuyện
Tham gia ngày
6 Tháng sáu 2008
Bài viết
1,668
Được thích
806
Điểm
968
Mình chỉnh 1 chút hàm ở dưới xem đúng không.Mình thấy 2 hàm này nó thế nào ấy.
Mã:
Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
Dim TmpStr As String, ArrStr, i As Long, TmpVal As Double, P1 As String, P2 As String, dk As String
   dk = Replace(Str, ",", ".")
If Len(dk) < 255 Then
    If Len(dk) > 0 Then
        Val = Evaluate("=" & dk)
        CalculateStr = CStr(Val)
    End If
Else
    If InStr(1, dk, "+") > 0 Then
        ArrStr = Split(dk, "+")
        For i = 0 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), TmpVal
            Val = Val + TmpVal
        Next
    ElseIf InStr(1, dk, "-") > 0 Then
        ArrStr = Split(dk, "-")
        CalculateStr ArrStr(0), Val
        Val = Val + TmpVal
        For i = 1 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), Val
            Val = Val - TmpVal
        Next
    Else
        P1 = InStrRev(dk, "*", 254):   P2 = InStrRev(dk, "/", 254)
        i = IIf(P1 > P2, P1, P1)
        If i = 0 Then
            CalculateStr = " " * " " ' Error
        Else
            TmpVal = Evaluate("=" & Left(Str, i - 1))
            CalculateStr = CalculateStr(CStr(TmpVal) & Mid(Str, i), Val)
        End If
    End If
End If
End Function
Sao anh không check lấy dấu của Windows
 

HieuCD

Chuyên gia GPE
Tham gia ngày
14 Tháng chín 2010
Bài viết
7,801
Được thích
15,675
Điểm
4,668
Dear all
Nhờ mọi người chỉnh sửa giúp mình code tính tổng này với. Code này trước mình xin được của 1 bác trên đây. code ở máy mình thì chạy ra kết quả bình thường không vấn đề ji. nhưng copy file excel sang file khác thì báo lỗi # Value. Mình đang nghĩ là do khác nhau về dấu chấm, dấy phẩy trong Excel của mỗi máy.


Mã:
Function DValue(ByVal Str As String) As Double
Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long, Val As Double
If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
Do
   StartGroup = InStr(StartGroup + 1, Str, "(")
   If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Val = 0
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1), Val) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        Else
            StartGroup = NextStartGroup
        End If
    Else
        CalculateStr Str, DValue
        Exit Function
    End If
Loop
End Function
Mã:
Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
Dim TmpStr As String, ArrStr, i As Long, TmpVal As Double, P1 As String, P2 As String
If Len(Str) < 255 Then
    If Len(Str) > 0 Then
        Val = Evaluate("=" & Str)
        CalculateStr = CStr(Val)
    End If
Else
    If InStr(1, Str, "+") > 0 Then
        ArrStr = Split(Str, "+")
        For i = 0 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), TmpVal
            Val = Val + TmpVal
        Next
    ElseIf InStr(1, Str, "-") > 0 Then
        ArrStr = Split(Str, "-")
        CalculateStr ArrStr(0), Val
        Val = Val + TmpVal
        For i = 1 To UBound(ArrStr, 1)
            CalculateStr ArrStr(i), Val
            Val = Val - TmpVal
        Next
    Else
        P1 = InStrRev(Str, "*", 254):   P2 = InStrRev(Str, "/", 254)
        i = IIf(P1 > P2, P1, P1)
        If i = 0 Then
            CalculateStr = " " * " " ' Error
        Else
            TmpVal = Evaluate("=" & Left(Str, i - 1))
            CalculateStr = CalculateStr(CStr(TmpVal) & Mid(Str, i), Val)
        End If
    End If
End If
End Function
Thử Function
Mã:
Function DValue(ByVal Str As String) As Double
  Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long, Val As Double
  If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
  Do
   If InStr(1, Str, ",") Then Str = Replace(Str, ",", ".")
   StartGroup = InStr(StartGroup + 1, Str, "(")
   If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Val = 0
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1), Val) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        Else
            StartGroup = NextStartGroup
        End If
    Else
        CalculateStr Str, DValue
        Exit Function
    End If
Loop
End Function

Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
Dim TmpStr As String, ArrStr, i As Long, TmpVal As Double, P1 As String, P2 As String
If Len(Str) < 255 Then
    If Len(Str) > 0 Then
        Val = Evaluate("=" & Str)
        CalculateStr = CStr(Val)
    End If
Else
  For j = 255 To 2
    If InStr(1, "+-", Mid(Str, j, 1)) > 0 Then
      Val = Val + Evaluate("=" & Mid(Str, 1, j - 1))
      CalculateStr Val & Mid(Str, j), Val
    End If
  Next j
End If
End Function
 

batman1

Thành viên gạo cội
Tham gia ngày
8 Tháng chín 2014
Bài viết
4,074
Được thích
6,447
Điểm
2,568
code ở máy mình thì chạy ra kết quả bình thường không vấn đề ji
Có vấn đề.
trước mình cũng dùng hàm này rồi. nhưng có những hàng quá 255 ký tự nên mình mới chuyển sang dùng code như vậy.
Hình như code không được đúng lắm.

Do bạn không mô tả dữ liệu nên tôi không biết cột G có dạng như thế nào. Tôi chỉ thử thôi.

Hiện tại G63 có 105 ký tự:

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)

Và H63 = 93.94.

Tôi chuyển thành (G63 có 317 ký tự):

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)

Tức lặp lại chuỗi có 105 ký tự 3 lần và cộng chúng với nhau. Tôi mong đợi H63 = 281.82. Nhưng kết quả lại là #VALUE!

Nếu tôi nhìn không nhầm thì G63 có dạng hợp lệ. Mỗi "(" có ") tương ứng.

Nguyên nhân không phải do G63 có 317 ký tự.

Ta chuyển
Mã:
If Len(Str) > 0 Then
    Val = Evaluate("=" & Str)
    CalculateStr = CStr(Val)
End If
thành
Mã:
If Len(Str) > 0 Then
    Debug.Print Str
    Val = Evaluate("=" & Str)
    CalculateStr = CStr(Val)
End If
và chạy code cho H63 thì trong cửa sổ Immediate sẽ có
6.68+9.39+3.9
6.68+9.39+3.9
6.68+9.39+3.9
(3.3

Rõ ràng với str = "(3.3" thì Evaluate("=" & Str) sẽ có lỗi và hàm DValue sẽ kết thúc với kết quả là #VALUE!

Nếu ta có G63 (65 ký tự):

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2) thì H63 = 59.23.

Bây giờ đổi thành (329 ký tự):

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)

Tức cộng 5 đoạn ngắn 65 ký tự. Ta mong đợi kết quả H63 = 5*59.23 = 296.15. Và ta nhận được. H63 = 296.15.

Vậy ở trên sai không phải do ký tự quá nhiều.

Sợ nhất là những code cho kết quả "may, rủi". Vì không biết lúc nào "rủi" để mà xử lý. :D
 

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0
Có vấn đề.

Hình như code không được đúng lắm.

Do bạn không mô tả dữ liệu nên tôi không biết cột G có dạng như thế nào. Tôi chỉ thử thôi.

Hiện tại G63 có 105 ký tự:

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)

Và H63 = 93.94.

Tôi chuyển thành (G63 có 317 ký tự):

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)

Tức lặp lại chuỗi có 105 ký tự 3 lần và cộng chúng với nhau. Tôi mong đợi H63 = 281.82. Nhưng kết quả lại là #VALUE!

Nếu tôi nhìn không nhầm thì G63 có dạng hợp lệ. Mỗi "(" có ") tương ứng.

Nguyên nhân không phải do G63 có 317 ký tự.

Ta chuyển
Mã:
If Len(Str) > 0 Then
    Val = Evaluate("=" & Str)
    CalculateStr = CStr(Val)
End If
thành
Mã:
If Len(Str) > 0 Then
    Debug.Print Str
    Val = Evaluate("=" & Str)
    CalculateStr = CStr(Val)
End If
và chạy code cho H63 thì trong cửa sổ Immediate sẽ có
6.68+9.39+3.9
6.68+9.39+3.9
6.68+9.39+3.9
(3.3

Rõ ràng với str = "(3.3" thì Evaluate("=" & Str) sẽ có lỗi và hàm DValue sẽ kết thúc với kết quả là #VALUE!

Nếu ta có G63 (65 ký tự):

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2) thì H63 = 59.23.

Bây giờ đổi thành (329 ký tự):

G63 = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2)

Tức cộng 5 đoạn ngắn 65 ký tự. Ta mong đợi kết quả H63 = 5*59.23 = 296.15. Và ta nhận được. H63 = 296.15.

Vậy ở trên sai không phải do ký tự quá nhiều.

Sợ nhất là những code cho kết quả "may, rủi". Vì không biết lúc nào "rủi" để mà xử lý. :D
Cảm ơn bác đã chỉ ra cái sai, cái không đúng khi chạy code ko ra kết quả chính xác. mình đã thử lại, thì đúng là như vậy. vậy Bác có thế fix giúp code này được không? mình cảm ơn nhiều.

223291
 

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0
Thử Function
Mã:
Function DValue(ByVal Str As String) As Double
  Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long, Val As Double
  If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
  Do
   If InStr(1, Str, ",") Then Str = Replace(Str, ",", ".")
   StartGroup = InStr(StartGroup + 1, Str, "(")
   If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Val = 0
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1), Val) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        Else
            StartGroup = NextStartGroup
        End If
    Else
        CalculateStr Str, DValue
        Exit Function
    End If
Loop
End Function

Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
Dim TmpStr As String, ArrStr, i As Long, TmpVal As Double, P1 As String, P2 As String
If Len(Str) < 255 Then
    If Len(Str) > 0 Then
        Val = Evaluate("=" & Str)
        CalculateStr = CStr(Val)
    End If
Else
  For j = 255 To 2
    If InStr(1, "+-", Mid(Str, j, 1)) > 0 Then
      Val = Val + Evaluate("=" & Mid(Str, 1, j - 1))
      CalculateStr Val & Mid(Str, j), Val
    End If
  Next j
End If
End Function

Mình đã thử code . nhưng có 1 vấn đề đó là khi chuỗi nhiều hơn 352 ký tự mà sự dụng nhiều ngoặc "(", ")" thì sẽ trả kể quả về giá trị "0".
thanks

223294
 

HieuCD

Chuyên gia GPE
Tham gia ngày
14 Tháng chín 2010
Bài viết
7,801
Được thích
15,675
Điểm
4,668
Mình đã thử code . nhưng có 1 vấn đề đó là khi chuỗi nhiều hơn 352 ký tự mà sự dụng nhiều ngoặc "(", ")" thì sẽ trả kể quả về giá trị "0".
Cảm ơn

View attachment 223294
Rút gọn Function
Mã:
Function DValue(ByVal Str As String) As Double
  Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long, Val As Double
  If Len(Str) = 0 Then Exit Function
  If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
  Do
    If InStr(1, Str, ",") Then Str = Replace(Str, ",", ".")
    StartGroup = InStr(StartGroup + 1, Str, "(")
    If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Val = 0
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1), Val) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        Else
            StartGroup = NextStartGroup
        End If
      Else
        CalculateStr Str, DValue
        Exit Function
    End If
  Loop
End Function

Private Function CalculateStr(ByVal Str As String, ByRef Val As Double) As String
  Dim j As Long
  Do While Len(Str) >= 255
    For j = 255 To 2 Step -1
      If InStr(1, "+-", Mid(Str, j, 1)) > 0 Then
        Val = Evaluate("=" & Mid(Str, 1, j - 1))
        Str = Val & Mid(Str, j)
        Exit For
      End If
    Next j
  Loop
  Val = Evaluate("=" & Str)
  CalculateStr = CStr(Val)
End Function
 

batman1

Thành viên gạo cội
Tham gia ngày
8 Tháng chín 2014
Bài viết
4,074
Được thích
6,447
Điểm
2,568
Chưa chuẩn. :D

Chắc chắn có lỗi vd. với

G63 ( 317 ký tự)) = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)

Nhưng cũng chả cần dài thế. Chắc chắn có lỗi vd. với

G63 (258 ký tự) =
3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2*2+2.07+3.82+2.21+1.02+19.97+3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2*2+2.07+3.82+2.21+1.02+19.97+3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+((1+3)*7-2.45)
 

HieuCD

Chuyên gia GPE
Tham gia ngày
14 Tháng chín 2010
Bài viết
7,801
Được thích
15,675
Điểm
4,668
Chưa chuẩn. :D

Chắc chắn có lỗi vd. với

G63 ( 317 ký tự)) = (3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)+(3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+(5.42+0.2)*2+2.07+3.82+2.21+1.02)+(6.68+9.39+3.9)

Nhưng cũng chả cần dài thế. Chắc chắn có lỗi vd. với

G63 (258 ký tự) =
3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2*2+2.07+3.82+2.21+1.02+19.97+3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+0.2*2+2.07+3.82+2.21+1.02+19.97+3.3+0.7+5.03+2.5*2+2+7.45+2*2+4.15*2+2+12.88+1.48+1.47+5.42+((1+3)*7-2.45)
Cắt bớt các lệnh không cần
Mã:
Function DValue(ByVal Str As String) As Double
  Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long
  If Len(Str) = 0 Then Exit Function
  If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
  Do
    If InStr(1, Str, ",") Then Str = Replace(Str, ",", ".")
    StartGroup = InStr(StartGroup + 1, Str, "(")
    If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1)) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        End If
    Else
        DValue = CalculateStr(Str)
        Exit Function
    End If
  Loop
End Function

Private Function CalculateStr(ByVal Str As String) As String
  Dim j As Long, Val As Double
  Do While Len(Str) >= 255
    For j = 255 To 2 Step -1
      If InStr(1, "+-", Mid(Str, j, 1)) > 0 Then
        Val = Evaluate("=" & Mid(Str, 1, j - 1))
        Str = Val & Mid(Str, j)
        Exit For
      End If
    Next j
  Loop
  CalculateStr = CStr(Evaluate("=" & Str))
End Function
 

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0
Cắt bớt các lệnh không cần
Mã:
Function DValue(ByVal Str As String) As Double
  Dim StartGroup As Long, NextStartGroup As Long, EndGroup As Long
  If Len(Str) = 0 Then Exit Function
  If Left(Str, 1) = "=" Then Str = Mid(Str, 2)
  Do
    If InStr(1, Str, ",") Then Str = Replace(Str, ",", ".")
    StartGroup = InStr(StartGroup + 1, Str, "(")
    If StartGroup > 0 Then
        NextStartGroup = InStr(StartGroup + 1, Str & "(", "(")
        EndGroup = InStr(StartGroup + 1, Str, ")")
        If EndGroup < NextStartGroup Then
            Str = Left(Str, StartGroup - 1) & CalculateStr(Mid(Str, StartGroup + 1, EndGroup - StartGroup - 1)) & Mid(Str, EndGroup + 1)
            StartGroup = 0
        End If
    Else
        DValue = CalculateStr(Str)
        Exit Function
    End If
  Loop
End Function

Private Function CalculateStr(ByVal Str As String) As String
  Dim j As Long, Val As Double
  Do While Len(Str) >= 255
    For j = 255 To 2 Step -1
      If InStr(1, "+-", Mid(Str, j, 1)) > 0 Then
        Val = Evaluate("=" & Mid(Str, 1, j - 1))
        Str = Val & Mid(Str, j)
        Exit For
      End If
    Next j
  Loop
  CalculateStr = CStr(Evaluate("=" & Str))
End Function
Cảm ơn Bác. mình đang chạy thử code này thì thấy fix được lỗi phân biệt dấu chấm, dấu phẩy trên máy khác. và fix đc lỗi vượt quá số lượng 352 ký tự trong chuỗi.
223316
 

batman1

Thành viên gạo cội
Tham gia ngày
8 Tháng chín 2014
Bài viết
4,074
Được thích
6,447
Điểm
2,568
Chắc chắn đây là lần lưu ý cuối cùng. :D

Có 1 trường hợp tôi cho là khó sảy ra. Khó sảy ra hay chắc chắn không sảy ra thì khó nói vì chủ thớt không mô tả dữ liệu. Không biết các dãy dài tùy ý được tạo như thế nào, các dạng có thể có.

Trường hợp khó sảy ra trong thực tế nhưng về lý thuyết có thể sảy ra. Việc sửa code để xử lý cả trường hợp này là rất dễ vì chỉ cần xét thêm trường hợp này.

Trường hợp nào? Khi ta có (260 ký tự):

G63 = 1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35

thì code "đơ" và không có kết quả.
 

HieuCD

Chuyên gia GPE
Tham gia ngày
14 Tháng chín 2010
Bài viết
7,801
Được thích
15,675
Điểm
4,668
Chắc chắn đây là lần lưu ý cuối cùng. :D

Có 1 trường hợp tôi cho là khó sảy ra. Khó sảy ra hay chắc chắn không sảy ra thì khó nói vì chủ thớt không mô tả dữ liệu. Không biết các dãy dài tùy ý được tạo như thế nào, các dạng có thể có.

Trường hợp khó sảy ra trong thực tế nhưng về lý thuyết có thể sảy ra. Việc sửa code để xử lý cả trường hợp này là rất dễ vì chỉ cần xét thêm trường hợp này.

Trường hợp nào? Khi ta có (260 ký tự):

G63 = 1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35

thì code "đơ" và không có kết quả.
Mình đã nghĩ đến tình huống nầy và các tình huống khác như "/", "^" ... , nhưng không xét vì không muốn viết cho tất cả tình huống có thể xảy ra với xác suất hầu như bằng 0 trong các bài toán bình thường
 

daimc

Thành viên mới
Tham gia ngày
10 Tháng bảy 2015
Bài viết
9
Được thích
2
Điểm
0
Chắc chắn đây là lần lưu ý cuối cùng. :D

Có 1 trường hợp tôi cho là khó sảy ra. Khó sảy ra hay chắc chắn không sảy ra thì khó nói vì chủ thớt không mô tả dữ liệu. Không biết các dãy dài tùy ý được tạo như thế nào, các dạng có thể có.

Trường hợp khó sảy ra trong thực tế nhưng về lý thuyết có thể sảy ra. Việc sửa code để xử lý cả trường hợp này là rất dễ vì chỉ cần xét thêm trường hợp này.

Trường hợp nào? Khi ta có (260 ký tự):

G63 = 1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35*1*4*0.35

thì code "đơ" và không có kết quả.
Cảm ơn Bác đã check code và đưa các trường hợp xảy ra để xử lý lỗi.
Dữ liệu của ổ G63: là phép tính tổng khối lượng của các đoạn cáp điện từ tủ đến đèn, từ đèn này qua đèn khác.( có những đoạn lặp lại thì nhân 2 hoặc 3).
Đúng là trường hợp tất cả phép tính đều nhân như kia thì sẽ không xảy ra, nhưng dù sao cũng cảm ơn bác, mình sẽ chú ý khi sử dụng code.
 
Quảng cáo
Top Bottom