Hỏi về hàm hoặc code diễn giải cách tính

Liên hệ QC

civil

Thành viên mới
Tham gia
19/8/07
Bài viết
12
Được thích
0
Nghề nghiệp
Civil engineer
Mình có vấn đề thế này:
ô "A1" có giá trị là: 5
ô "A2" có giá trị là: 3
ô "A3" có giá trị là: 9
ô "A4" có giá trị là: =A1+A2-A3
Cho mình hỏi có hàm nào trong excel hoặc có macro nào để mình làm việc sau:
Đánh vào "A5" hàm: =diendai(A4)
Thì ô A5 hiện ra gia trị : 5+3-9
Cám ơn mọi người
 
Lần chỉnh sửa cuối:
Lấy ý từ Function FD(mycell) của ttphong2007 cải biên lại theo ý của civil
Mã:
Function DienGiai(mycell) As String
If mycell = "" Then
  DienGiai = ""
ElseIf Left(mycell.Formula, 1) <> "=" Then
  DienGiai = mycell
Else
 ct = Mid(mycell.Formula, 2)
  n = 1
  m = 1
  Do
    dau = Mid(ct, n, 1)
    If dau = "+" Or dau = "-" Or dau = "*" Or dau = "/" Or dau = "(" Or dau = ")" Or dau = "{" Or dau = "}" Or dau = "[" Or dau = "]" Then
      If n = m Then
        DienGiai = DienGiai & dau
      Else
        conso = Range(Mid(ct, m, n - m)).Value
        DienGiai = DienGiai & conso & dau
      End If
      m = n + 1
    ElseIf n = Len(ct) Then
      conso = Range(Mid(ct, m)).Value
      DienGiai = DienGiai & conso
      Exit Do
    End If
    n = n + 1
  Loop While n <= Len(ct)
End If
End Function
 
Upvote 0
Bạn dùng tạm đoạn code sau.
Mới chỉ áp dụng được với các phép toán +, -, *, /, \, ^ thôi và chưa tính đến có dấu (), {}, [],...
Mã:
Option Explicit
Public Function Diengiai(rngData As Range)
    Dim strText As String, strText2 As String
    Dim i As Long, j As Long
    Dim subText() As String, dau() As String
    
    strText = rngData.Formula
    
    For i = 1 To Len(strText)
        Select Case Mid(strText, i, 1)
            Case "+", "-", "*", "/", "^"
                ReDim Preserve dau(j)
                dau(j) = Mid(strText, i, 1)
                j = j + 1
        End Select
    Next i
    
    strText = Replace(strText, "=", "")
    strText = Replace(strText, "+", "@")
    strText = Replace(strText, "-", "@")
    strText = Replace(strText, "*", "@")
    strText = Replace(strText, "/", "@")
    strText = Replace(strText, "\", "@")
    strText = Replace(strText, "^", "@")
    strText = Replace(strText, "(", "")
    strText = Replace(strText, ")", "")
    strText = Trim(strText)
        
    subText = Split(strText, "@")
    
    For i = 0 To UBound(subText)
        If Not IsNumeric(subText(i)) Then
            subText(i) = Range(subText(i)).Value
        End If
    Next i
    
    ReDim Preserve dau(UBound(subText))
    For i = 0 To UBound(subText)
        strText2 = strText2 & subText(i) & dau(i)
    Next i
    
    Diengiai = strText2
End Function

Em sài cái này nhiều rồi. Nhưng có vấn đề là nếu ô chứa số liệu thập phân quá nhiều thì nó cũng liệt kê dài ngoằn theo luôn.
Theo tinh thần là hoàn thiện đoạn code trên, nếu như muốn ô diễn giải này nó tinh gọn thì lọc lại giá trị sau dấu "." để làm tròn số rồi hiển thị hổng biết anh làm được không.

Ví dụ như : ô A1 = 43.1368434184 và ô A2 = 25.68464134
thì khi diễn giải ô A3 = A 1 + A 2 thì nó hiện nguyên hình thế này "= 43.1368434184 + 25.68464134" . Khá nhức mắt, em muốn nó chỉ đơn giản là hiện thế này "= 43.14 + 25.68"
Rất mong nhận được ý kiến đóng góp.
 
Upvote 0
Em sài cái này nhiều rồi. Nhưng có vấn đề là nếu ô chứa số liệu thập phân quá nhiều thì nó cũng liệt kê dài ngoằn theo luôn.
Theo tinh thần là hoàn thiện đoạn code trên, nếu như muốn ô diễn giải này nó tinh gọn thì lọc lại giá trị sau dấu "." để làm tròn số rồi hiển thị hổng biết anh làm được không.

Ví dụ như : ô A1 = 43.1368434184 và ô A2 = 25.68464134
thì khi diễn giải ô A3 = A 1 + A 2 thì nó hiện nguyên hình thế này "= 43.1368434184 + 25.68464134" . Khá nhức mắt, em muốn nó chỉ đơn giản là hiện thế này "= 43.14 + 25.68"
Rất mong nhận được ý kiến đóng góp.

Bạn tham khảo nhé:
Mã:
Option Explicit
Public Function Diengiai(rngData As Range)
    On Error Resume Next
    Dim strText As String, strText2 As String
    Dim i As Long, j As Long
    Dim k
    Dim subText() As String, dau() As String
    
    strText = rngData.Formula
    strText = Trim$(Replace(strText, "=", ""))
    
    For i = 1 To Len(strText)
        Select Case Mid(strText, i, 1)
            Case "+", "-", "*", "/", "^", "(", ")"
                ReDim Preserve dau(j)
                dau(j) = Mid(strText, i, 1)
                j = j + 1
        End Select
    Next i
    
    
    strText = Replace(strText, "+", "@")
    strText = Replace(strText, "-", "@")
    strText = Replace(strText, "*", "@")
    strText = Replace(strText, "/", "@")
    strText = Replace(strText, "\", "@")
    strText = Replace(strText, "^", "@")
    strText = Replace(strText, "(", "@")
    strText = Replace(strText, ")", "@")
            
    subText = Split(strText, "@")
  
    For i = 0 To UBound(subText)
        If Not IsNumeric(subText(i)) Then
            Err.Clear
            k = Range(subText(i))
            
            If Err.Number <> 0 Then
                If Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat <> "General" Then
                    subText(i) = Format$(Range(subText(i)).Value, Range(subText(i)).NumberFormat)
                ElseIf Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat = "General" Then
                    subText(i) = Range(subText(i)).Value
                End If
            Else
                subText(i) = subText(i)
            End If
            
        End If
    Next i
        
    ReDim Preserve dau(UBound(subText))
    
    For i = 0 To UBound(subText)
        strText2 = strText2 & subText(i) & dau(i)
    Next i
    
    Diengiai = strText2
End Function

Đoạn Code trên chấp nhận trong công thức có cả dấu ngoặc và các hàm của MS Excel
P/S: Số ký tự sau dấu (.) sẽ được lấy theo đúng định dạng của ô.
 
Lần chỉnh sửa cuối:
Upvote 0
Bạn tham khảo nhé:

Đoạn Code trên chấp nhận trong công thức có cả dấu ngoặc và các hàm của MS Excel
P/S: Số ký tự sau dấu (.) sẽ được lấy theo đúng định dạng của ô.
E24 = 2/3 = 0.333
E23 = 5/6 = 0.833
Kết quả E27 = 1.166
E28 = diengiai(E27)
e28 hiện nguyên hình "E24+E23"
hổng hiểu.
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Sorry! Hi hi
Bạn sửa dấu <> 0 thành = 0 nhé
Mã:
Option Explicit
Public Function Diengiai(rngData As Range)
    On Error Resume Next
    Dim strText As String, strText2 As String
    Dim i As Long, j As Long
    Dim k
    Dim subText() As String, dau() As String
    
    strText = rngData.Formula
    
    For i = 1 To Len(strText)
        Select Case Mid(strText, i, 1)
            Case "+", "-", "*", "/", "^", "(", ")"
                ReDim Preserve dau(j)
                dau(j) = Mid(strText, i, 1)
                j = j + 1
        End Select
    Next i
    
    strText = Trim$(Replace(strText, "=", ""))
    strText = Replace(strText, "+", "@")
    strText = Replace(strText, "-", "@")
    strText = Replace(strText, "*", "@")
    strText = Replace(strText, "/", "@")
    strText = Replace(strText, "\", "@")
    strText = Replace(strText, "^", "@")
    strText = Replace(strText, "(", "@")
    strText = Replace(strText, ")", "@")
            
    subText = Split(strText, "@")
  
    For i = 0 To UBound(subText)
        If Not IsNumeric(subText(i)) Then
            Err.Clear
            k = Range(subText(i))
            
            If Err.Number [B][COLOR=#ff0000]=[/COLOR][/B] 0 Then
                If Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat <> "General" Then
                    subText(i) = Format$(Range(subText(i)).Value, Range(subText(i)).NumberFormat)
                ElseIf Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat = "General" Then
                    subText(i) = Range(subText(i)).Value
                End If
            End If
            
        End If
    Next i
        
    ReDim Preserve dau(UBound(subText))
    
    For i = 0 To UBound(subText)
        strText2 = strText2 & subText(i) & dau(i)
    Next i
    
    Diengiai = strText2
End Function

Bạn đừng quá khen vội.
Trong code trên chưa "diễn giải" được các thông số nếu bạn sử dụng một hàm Excel nào đó.
Ví dụ:
A5 = ((22+A3)*4.5)*4+A2*(A3/2-A1)*5+A4^2+SUM(A1:A4)
B5 = diengiai(A5) = ............^2+SUM(A1:A4)
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Có một vấn đề phát sinh là khi em làm nối phép tính ở một giá trị ở sheet khác thì nó hiển thị địa chỉ ô thay vì giá trị của ô đó. Bác nvson có thể nào giúp em vấn đề này được không ?
Ví dụ ở sheet 1 có A1 = 567
sheet 2 có B1 = 789

Sheet 1 gõ ô A2 = A1 + Sheet2'B1 thì có hiện là 567 + Sheet2!B1

Trong khi cái code diengiai trước kia chỉ mỗi tội là không lượt bớt số thập phân nhưng nó hiển thị kết quả.
 
Upvote 0
Có một vấn đề phát sinh là khi em làm nối phép tính ở một giá trị ở sheet khác thì nó hiển thị địa chỉ ô thay vì giá trị của ô đó. Bác nvson có thể nào giúp em vấn đề này được không ?
Ví dụ ở sheet 1 có A1 = 567
sheet 2 có B1 = 789

Sheet 1 gõ ô A2 = A1 + Sheet2'B1 thì có hiện là 567 + Sheet2!B1

Trong khi cái code diengiai trước kia chỉ mỗi tội là không lượt bớt số thập phân nhưng nó hiển thị kết quả.

Em tìm ra nguyên nhân là nó có số 0 thì sẽ bất lực bác à.
 
Upvote 0
Sheet 1 gõ ô A2 = A1 + Sheet2'B1 thì có hiện là 567 + Sheet2!B1

Trong khi cái code diengiai trước kia chỉ mỗi tội là không lượt bớt số thập phân nhưng nó hiển thị kết quả.
Bạn sử dụng code sau nhé:
Đoạn code này sẽ đóng ngoặc giá trị âm. Mình không chuyển -- thành +, +- thành - ... vì mình muốn giữ lại các dấu công thức cũ.
Mã:
Option Explicit
Public Function Diengiai(rngData As Range)
    On Error Resume Next
    Dim strText As String, strText2 As String
    Dim i As Long, j As Long
    Dim k
    Dim subText() As String, dau() As String
    
    strText = rngData.Formula
    
    For i = 1 To Len(strText)
        Select Case Mid(strText, i, 1)
            Case "+", "-", "*", "/", "^", "(", ")"
                ReDim Preserve dau(j)
                dau(j) = Mid(strText, i, 1)
                j = j + 1
        End Select
    Next i
    
    strText = Trim$(Replace(strText, "=", ""))
    strText = Replace(strText, "+", "@")
    strText = Replace(strText, "-", "@")
    strText = Replace(strText, "*", "@")
    strText = Replace(strText, "/", "@")
    strText = Replace(strText, "\", "@")
    strText = Replace(strText, "^", "@")
    strText = Replace(strText, "(", "@")
    strText = Replace(strText, ")", "@")
            
    subText = Split(strText, "@")
  
    For i = 0 To UBound(subText)
        If Not IsNumeric(subText(i)) Then
            Err.Clear
            k = Range(subText(i))
            
            If Err.Number = 0 Then
                If Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat <> "General" Then
                    subText(i) = Format$(Range(subText(i)).Value, Range(subText(i)).NumberFormat)
                ElseIf Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat = "General" Then
                    subText(i) = Range(subText(i)).Value
                End If
            Else
                subText(i) = subText(i)
            End If
            If Left(subText(i), 1) = "-" Then subText(i) = "(" & subText(i) & ")"
        End If
    Next i
        
    ReDim Preserve dau(UBound(subText))
    
    For i = 0 To UBound(subText)
        strText2 = strText2 & subText(i) & dau(i)
    Next i
    
    Diengiai = strText2
End Function

Em tìm ra nguyên nhân là nó có số 0 thì sẽ bất lực bác à.
Cái này mình chưa hiểu lắm...
 
Upvote 0
Mình có 1 vấn đề tương tự như vậy nhưng mình muốn nhập diễn giải cách tính sau đó thì cột khối lượng tư tính khối lượng không cần nhập lại cách tính. Mình cácm ơn bạn rất nhiều!
 

File đính kèm

  • KL-chitiet.xls
    23.5 KB · Đọc: 12
Upvote 0
Upvote 0
Bạn sử dụng code sau nhé:
Đoạn code này sẽ đóng ngoặc giá trị âm. Mình không chuyển -- thành +, +- thành - ... vì mình muốn giữ lại các dấu công thức cũ.
Mã:
Option Explicit
Public Function Diengiai(rngData As Range)
    On Error Resume Next
    Dim strText As String, strText2 As String
    Dim i As Long, j As Long
    Dim k
    Dim subText() As String, dau() As String
    
    strText = rngData.Formula
    
    For i = 1 To Len(strText)
        Select Case Mid(strText, i, 1)
            Case "+", "-", "*", "/", "^", "(", ")"
                ReDim Preserve dau(j)
                dau(j) = Mid(strText, i, 1)
                j = j + 1
        End Select
    Next i
    
    strText = Trim$(Replace(strText, "=", ""))
    strText = Replace(strText, "+", "@")
    strText = Replace(strText, "-", "@")
    strText = Replace(strText, "*", "@")
    strText = Replace(strText, "/", "@")
    strText = Replace(strText, "\", "@")
    strText = Replace(strText, "^", "@")
    strText = Replace(strText, "(", "@")
    strText = Replace(strText, ")", "@")
            
    subText = Split(strText, "@")
  
    For i = 0 To UBound(subText)
        If Not IsNumeric(subText(i)) Then
            Err.Clear
            k = Range(subText(i))
            
            If Err.Number = 0 Then
                If Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat <> "General" Then
                    subText(i) = Format$(Range(subText(i)).Value, Range(subText(i)).NumberFormat)
                ElseIf Len(Range(subText(i))) > 0 And Range(subText(i)).NumberFormat = "General" Then
                    subText(i) = Range(subText(i)).Value
                End If
            Else
                subText(i) = subText(i)
            End If
            If Left(subText(i), 1) = "-" Then subText(i) = "(" & subText(i) & ")"
        End If
    Next i
        
    ReDim Preserve dau(UBound(subText))
    
    For i = 0 To UBound(subText)
        strText2 = strText2 & subText(i) & dau(i)
    Next i
    
    Diengiai = strText2
End Function


Cái này mình chưa hiểu lắm...

Tức là với ô có giá trị là rỗng hoặc = 0 thì trên công thức diengiai chỉ cho kết quả là địa chỉ của đối tượng cell
 
Upvote 0
Mình thấy ô có giá trị là 0 thì trong công thúc diengiai đúng đấy chứ.
Code sau sẽ thay đổi ô có giá trị rỗng được thay bằng 0, nếu bạn muốn thay bằng một giá trị khác thì thay đổi dòng lệnh màu đỏ nhé.
Mã:
Option Explicit
Public Function Diengiai(rngData As Range)
    On Error Resume Next
    Dim strText As String, strText2 As String
    Dim i As Long, j As Long
    Dim k
    Dim subText() As String, dau() As String
    
    strText = rngData.Formula
    
    For i = 1 To Len(strText)
        Select Case Mid(strText, i, 1)
            Case "+", "-", "*", "/", "^", "(", ")"
                ReDim Preserve dau(j)
                dau(j) = Mid(strText, i, 1)
                j = j + 1
        End Select
    Next i
    
    strText = Trim$(Replace(strText, "=", ""))
    strText = Replace(strText, "+", "@")
    strText = Replace(strText, "-", "@")
    strText = Replace(strText, "*", "@")
    strText = Replace(strText, "/", "@")
    strText = Replace(strText, "\", "@")
    strText = Replace(strText, "^", "@")
    strText = Replace(strText, "(", "@")
    strText = Replace(strText, ")", "@")
            
    subText = Split(strText, "@")
  
    For i = 0 To UBound(subText)
        If Not IsNumeric(subText(i)) Then
            Err.Clear
            k = Range(subText(i))
            
            If Err.Number = 0 Then
                [B][COLOR=#ff0000]If IsEmpty(Range(subText(i))) Then subText(i) = 0
[/COLOR][/B]                If Range(subText(i)).NumberFormat <> "General" Then
                    subText(i) = Format$(Range(subText(i)).Value, Range(subText(i)).NumberFormat)
                ElseIf Range(subText(i)).NumberFormat = "General" Then
                    subText(i) = Range(subText(i)).Value
                End If
            Else
                subText(i) = subText(i)
            End If
            If Left(subText(i), 1) = "-" Then subText(i) = "(" & subText(i) & ")"
        End If
    Next i
        
    ReDim Preserve dau(UBound(subText))
    
    For i = 0 To UBound(subText)
        strText2 = strText2 & subText(i) & dau(i)
    Next i
    
    Diengiai = strText2
End Function
 
Upvote 0
Sao mình làm không được nhỉ, nhờ các bạn giúp mình với. Cam ơn rất nhiều!
 

File đính kèm

  • DienGiai.rar
    23.3 KB · Đọc: 29
Upvote 0
Các cao thủ cho minh hỏi cái, ví dụ như ô E2 và E3 mình đăt name với tên ứng với ô bên cột D2 và D3 ở ô E4 mình muốn sử dụng một hàm tính cái diễn giải cách tính bên ô C4 và những giá trị các ô E2 và E3 thay đổi thì ô e4 cũng thay đổi theo có thể viết một hàm như vậy được không
 
Upvote 0
Web KT
Back
Top Bottom