Board logo

標題: [發問] EXCEL VBA 由計算說明計算金額(二) [打印本頁]

作者: ML089    時間: 2012-9-6 17:34     標題: EXCEL VBA 由計算說明計算金額(二)

原發問如下,是利用刪除字串來刪除部必要的字元
http://forum.twbts.com/thread-7705-1-1.html

因為前方式還不是很方便使用,希望設定簡單規則來刪除不必要的字元或是保留必要的字元
C欄計算說明中,只要保留 數字 0-9,運算符號 + - * / ^ % ,括號 ( ), 英文 a-z A-Z 其他刪除,
刪除後會變成標準計算式,再計算式放入D欄金額欄,為了方便檢查正確性,可否以公式方式放入。

[attach]12389[/attach]


檔案 [attach]12390[/attach]
作者: Hsieh    時間: 2012-9-6 18:19

回復 1# ML089
[attach]12391[/attach]
  1. Function MyCal(Mystr$) As Double
  2. Application.Volatile
  3. Set d = CreateObject("Scripting.Dictionary")
  4. ar = Array(40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 62, 91, 92, 93, 94, 95)
  5. For i = 0 To UBound(ar)
  6. d(Chr(ar(i))) = Chr(ar(i))
  7. Next
  8. For i = Len(Mystr) To 1 Step -1
  9. Mystr = Replace(Mystr, Mid(Mystr, i, 1), d(Mid(Mystr, i, 1)))
  10. Next
  11. MyCal = Evaluate(Mystr)
  12. End Function
複製代碼

作者: ML089    時間: 2012-9-7 14:01

回復 2# Hsieh
感謝回覆,
這次有 CreateObject("Scripting.Dictionary") 讓我一直看不懂,上網研究後大致已經懂了你的程式,
因為要修改去除的碼,重新依照你的公式構架編寫如下:

另外再補充請教一問題, Mid(字串, i, 1) 取出一字如何判定是中文字?

Function MyCal(MyStr$) As Double
    Application.Volatile
    Set d = CreateObject("Scripting.Dictionary")
    Dic = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789%+-*/^()"
    For i = 1 To Len(Dic)
        d(Mid(Dic, i, 1)) = Mid(Dic, i, 1)
    Next
    For i = Len(MyStr) To 1 Step -1
        MyStr = Replace(MyStr, Mid(MyStr, i, 1), d(Mid(MyStr, i, 1)))
    Next
    MyCal = Evaluate(MyStr)
End Function
作者: Hsieh    時間: 2012-9-7 15:21

回復 3# ML089
判斷是否為漢字,可利用ASC函數取得字元碼,小於0則為漢字
作者: ML089    時間: 2012-9-7 17:25

回復 4# Hsieh

感謝回覆

在EXCEL是用CODE,爾且碼是正數5位
在VBA是用ASC,爾且碼是負數5位
VBA的ASC與EXCEL的ASC是不同意義,
EXCEL的函數與VBA的函數不同名用法也不同,學習起來真是痛苦。
作者: chin15    時間: 2012-9-7 17:27

[attach]12401[/attach]
作者: ML089    時間: 2012-9-7 23:34

回復 6# chin15
哇! 使用 CreateObject("VBSCRIPT.REGEXP") 讓程式碼更短,真厲害
雖然看不懂,還是先給一個讚
EXCEL裡找不到說明,網路都是例子找不到完整說明,不知哪裡有說明可以看,可否告知 一下。
作者: chin15    時間: 2012-9-8 08:19

http://www.dotblogs.com.tw/yc421206/archive/2008/12/14/6386.aspx
作者: c_c_lai    時間: 2012-9-8 09:27

回復 1# ML089
提供你參考。
  1. Function decodeFMT(decode As String) As String
  2.     Dim tLen%, txt$, num$
  3.    
  4.     If Len(decode) = 0 Then decodeFMT = "": Exit Function
  5.     num = "=Sum("
  6.     For tLen = 1 To Len(decode)
  7.            txt = Mid(decode, tLen, 1)
  8.            If txt = "(" Or txt = ")" Or txt = "+" Or txt = "+" Or txt = "+" Or txt = "-" Or txt = "*" Or txt = "/" Or (txt >= "0" And txt <= "9") Then
  9.                 num = num + txt
  10.            End If
  11.     Next tLen
  12.     decodeFMT = num + ")"
  13. End Function
複製代碼
[attach]12410[/attach]
作者: ML089    時間: 2012-9-8 10:24

回復 8# chin15

說明清楚,感謝你,又讓我多學了好幾招,再給你一個 讚
作者: ML089    時間: 2012-9-8 10:31

回復 9# c_c_lai

謝謝你提供,在看你的公式時,也讓我想到另一種簡單寫法(列舉法)
Function MyCal(MyStr$) As Double
    Dim Dic As String, xStr As String
    Dic = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789%+-*/^()"
    For i = 1 To Len(MyStr)
        If InStrB(1, Dic, Mid(MyStr, i, 1), 1) <> 0 Then
            xStr = xStr & Mid(MyStr, i, 1)
        End If
    Next i
    MyCal = Evaluate(xStr)
End Function
作者: c_c_lai    時間: 2012-9-8 17:20

回復 11# ML089
一個是帶入公式、另一個直接換算為值,
都是蠻不錯且簡單的處理方式。




歡迎光臨 麻辣家族討論版版 (http://forum.twbts.com/)