Mỗi tuần một chuyên đề

Đưa công thức đã định nghĩa vào tính toán trong query

  • Thread starter ahp
  • Ngày gửi
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
Các cao thủ giúp em tý nhé, chuyện là thế này: em đang manh nha xây dựng một chương trình nhỏ tính lương lại cơ quan, hiện em đang vướng là chưa đưa được công thức đã định nghĩa vào cột tính trong query. cụ thể như sau
em có 3 tệp:

- Tệp Bangluong: chứa các dữ liệu lương và có các fiel: hsl(he so luong); ltt(luong toi thieu); nctt(ngay cong thuc te); tnc(tong ngay cong);tp(thoi gian nghi phep)
- tệp congthuctinhluong: co cac fiel: luongcb(luong co ban), luongp(luong phep)

trong fiel + luongcb: duoc dinh nghia: =hsl*ltt*nctt/tnc
+ luongp: duoc dinh nghia: =hsl*ltt*tp

Mục đích của em là tạo query với các fiel: hsl(đã ok); tnc(đã ok); nctt(đã ok); luongcb(được tính bằng cách dán công thức trên tep congthuctinhluong); luongp(được tính bằng cách dán công thức trên tep congthuctinhluong).

file day, cac bac bot chut thoi gian giup em voi
http://www.mediafire.com/?jnidt0rzmdm
 
Sửa lần cuối:
Khóa học Quản trị dòng tiền
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
Các cao thủ đi đâu hết rồi, ghé qua giúp em tý ạ:025:
 
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
to bidit

Bác up lại file hộ em với, cái đường dẫn trên báo "no file"
 
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
to bidit
Chán quá cụ ơi, cai file này em down về được nhưng lai báo " cant not open"
Cụ làm ơn giúp em tiếp nhé
 
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
To bidit
em đã mở được file của cụ, tuy nhiên cụ vẫn chưa hiểu ý em, vấn đề em muốn là làm sao dán(link) cái công thức tại tệp công thức vào query để khi em sửa chỉ cần định nghĩa lại tệp công thức, chứ đánh trực tiếp vào query thì thủ công quá.
 
S

spammail

Guest
Vấn đề này bạn phải viết hàm thôi :wall:.
Mình có viết cho bạn hàm, bạn chỉ cần truyền tham số vào thì dù công thức đó là cộng, trừ, nhân hay chia gì cũng có thể thực thi được.
Dòng 4 của câu query là ví dụ mình đổi công thức tính cho bạn. Mong bạn sẽ hiểu và từ đó triển khai cho cái cách tính lương khác.
 
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
Vấn đề này bạn phải viết hàm thôi :wall:.
Mình có viết cho bạn hàm, bạn chỉ cần truyền tham số vào thì dù công thức đó là cộng, trừ, nhân hay chia gì cũng có thể thực thi được.
Dòng 4 của câu query là ví dụ mình đổi công thức tính cho bạn. Mong bạn sẽ hiểu và từ đó triển khai cho cái cách tính lương khác.

trước hết rất cám ơn bác về việc mã hoá công thức nhúng công thức vô fiel, nhưng phương pháp này còn rất hạn chế đó là: số hạng trong công thức phải cố định về số lượng, vị trí và tên fiel.
Liệu có giải pháp nào mà với việc các công thức chỉ cần các số hạng trùng với fiel của tệp, còn em muon thay vị trí, số lượng, fiel mà vẫn được không bác

thanks
 
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
thanks mpv2006, bidit - cách của hai bác giống nhau
Em úp thêm đoạn mã để các bác tham khảo và sử dụng nhé, tương đương với đoạn mã của hai bác mpv và bidit, nhưng đơn giản hơn chút, không phải cắt xén chỉ cần đưa giá trị đầu vào.
Function congthuc(InForm As String, a As Long, b As Long, c As Long, d As Long) As Long
'Thay thế các đoạn chuỗi trong công thức bằng giá trị thật
InForm = Replace(InForm, "a", a)
InForm = Replace(InForm, "b", b)
InForm = Replace(InForm, "c", c)
InForm = Replace(InForm, "d", d)
'Gọi hàm Eval và tính toán rồi trả về kết quả cuối cùng
Congthuc = Eval(InForm)
End Function



Tuy nhiên em rất muốn phát triển theo hướng mở hơn tức là biểu thức của em có thể tăng biến số, đổi biến số, đổi vị trí với duy nhất một điều kiện đó là các biến hoàn toàn trùng tên với các fiel.

Em nhớ là trước em làm được với visual fox, mà bây giờ chưa làm được với access, lâu rồi không mần, bầy giờ tự nhiên lại hứng "ủa không có măt cười các bác nhỉ"

Rất mong các bác tiếp tục giúp đỡ
 
Sửa lần cuối:
M

mvp2006

Sơ cấp
16/10/08
36
0
0
TPHCM
thanks mpv2006, bidit - cách của hai bác giống nhau
Em úp thêm đoạn mã để các bác tham khảo và sử dụng nhé, tương đương với đoạn mã của hai bác mpv và bidit, nhưng đơn giản hơn chút, không phải cắt xén chỉ cần đưa giá trị đầu vào.
Function congthuc(InForm As String, a As Long, b As Long, c As Long, d As Long) As Long
'Thay thế các đoạn chuỗi trong công thức bằng giá trị thật
InForm = Replace(InForm, "a", a)
InForm = Replace(InForm, "b", b)
InForm = Replace(InForm, "c", c)
InForm = Replace(InForm, "d", d)
'Gọi hàm Eval và tính toán rồi trả về kết quả cuối cùng
Congthuc = Eval(InForm)
End Function



Tuy nhiên em rất muốn phát triển theo hướng mở hơn tức là biểu thức của em có thể tăng biến số, đổi biến số, đổi vị trí với duy nhất một điều kiện đó là các biến hoàn toàn trùng tên với các fiel.

Em nhớ là trước em làm được với visual fox, mà bây giờ chưa làm được với access, lâu rồi không mần, bầy giờ tự nhiên lại hứng "ủa không có măt cười các bác nhỉ"

Rất mong các bác tiếp tục giúp đỡ

Trước đây mình cũng có sử dụng Fox dùng linh hoạt các biến để thay thế các field, trong access hình như không được.
cách của mình bạn có đổi vị trí của các biến số trong công thức (mình cố tình đưa "HSL" vào trước "LTTKV3" trong query), chỉ có điều bạn phải dự tính trứơc có tối đa bao nhiêu biến số để khai báo (có thể khai báo thừa ra để phòng hờ), trong ví dụ công thức của bạn có 4 biến số, mình khai báo 5,bạn có thể tăng thêm. Trong query khi gọi hàm bạn nên đưa tất cả các trường dùng làm biến số, các trường nào dư cũng không sao.
 
Sửa lần cuối:
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
Rất cám ơn cụ mpv2006, em thấy rất hài lòng với giải pháp tăng biến số của cụ, một lần nữa cám ơn cụ, à mà cụ giúp em luôn cái topic copy table to table với
 
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
em xin phép được trở lại vấn đề này,

em đã dùng hàm sau để đưa công thức vào query:

Public Function LuongCB(Congthuc As String, Optional Fa1 As String = "", Optional F1 As Double = 0, _
Optional Fa2 As String = "", Optional F2 As Double = 0, Optional Fa3 As String = "", Optional F3 As Double = 0, _
Optional Fa4 As String = "", Optional F4 As Double = 0, Optional Fa5 As String = "", Optional F5 As Double = 0, _
Optional Fa6 As String = "", Optional F6 As Double = 0, Optional Fa7 As String = "", Optional F7 As Double = 0, _
Optional Fa8 As String = "", Optional F8 As Double = 0, Optional Fa9 As String = "", Optional F9 As Double = 0, _
Optional Fa10 As String = "", Optional F10 As Double = 0, Optional Fa11 As String = "", Optional F11 As Double = 0, _
Optional Fa12 As String = "", Optional F12 As Double = 0, Optional Fa13 As String = "", Optional F13 As Double = 0, _
Optional Fa14 As String = "", Optional F14 As Double = 0, Optional Fa15 As String = "", Optional F15 As Double = 0, _
Optional Fa16 As String = "", Optional F16 As Double = 0, Optional Fa17 As String = "", Optional F17 As Double = 0, _
Optional Fa18 As String = "", Optional F18 As Double = 0, Optional Fa19 As String = "", Optional F19 As Double = 0, _
Optional Fa20 As String = "", Optional F20 As Double = 0, Optional Fa21 As String = "", Optional F21 As Double = 0, _
Optional Fa22 As String = "", Optional F22 As Double = 0, Optional Fa23 As String = "", Optional F23 As Double = 0, _
Optional Fa24 As String = "", Optional F24 As Double = 0, Optional Fa25 As String = "", Optional F25 As Double = 0) As Variant
Congthuc = Replace(Congthuc, Fa1, F1)
Congthuc = Replace(Congthuc, Fa2, F2)
Congthuc = Replace(Congthuc, Fa3, F3)
Congthuc = Replace(Congthuc, Fa4, F4)
Congthuc = Replace(Congthuc, Fa5, F5)
Congthuc = Replace(Congthuc, Fa6, F6)
Congthuc = Replace(Congthuc, Fa7, F7)
Congthuc = Replace(Congthuc, Fa8, F8)
Congthuc = Replace(Congthuc, Fa9, F9)
Congthuc = Replace(Congthuc, Fa10, F10)
Congthuc = Replace(Congthuc, Fa11, F11)
Congthuc = Replace(Congthuc, Fa12, F12)
Congthuc = Replace(Congthuc, Fa13, F13)
Congthuc = Replace(Congthuc, Fa14, F14)
Congthuc = Replace(Congthuc, Fa15, F15)
Congthuc = Replace(Congthuc, Fa16, F16)
Congthuc = Replace(Congthuc, Fa17, F17)
Congthuc = Replace(Congthuc, Fa18, F18)
Congthuc = Replace(Congthuc, Fa19, F19)
Congthuc = Replace(Congthuc, Fa20, F20)
Congthuc = Replace(Congthuc, Fa21, F21)
Congthuc = Replace(Congthuc, Fa22, F22)
Congthuc = Replace(Congthuc, Fa23, F23)
Congthuc = Replace(Congthuc, Fa24, F24)
Congthuc = Replace(Congthuc, Fa25, F25)
LuongCB = Round(Eval(Congthuc), -3)
End Function

Tuy nhiên có một số hạn chế:
1. Hàm chỉ cho khai báo đến 25 biến như trên

2. Query thì lại cho khai báo ít hơn: chỉ được có 14 biến nếu khái báo hơn là báo lỗi ""the expression you entered is too complex"

luongLT: luongcb([LLT2],"hsl",[hsl],"hpc",[hpc],"lttkv3",[lttkv3],"tnc",[tnc],"tsp1",[tsp1],"tsp2",[tsp2],"tsp3",[tsp3],"1.5",1.5,"2",2,"3",3,"8",8,"ltt",[ltt],"qllt1",[qllt1],"0.8",(0.8))

Các bác có giải pháp nào khắc phục không ạ
 
paulsteigel

paulsteigel

Trung cấp
13/11/05
103
0
16
48
Hoà Bình
www.sfdp.net
Giới thiệu với bạn cách tiếp cận có thay đổi chút ít từ tiếp cận ban đầu của tôi tại địa chỉ http://www.webketoan.vn/forum/showthread.php?t=50357.
Với cách này thì tuy tốc độ có chậm nhưng khắc phục được một số hạn chế khi đưa những phép toán phức tạp vào câu truy vấn.

Mã:
Function ProcessFomulaX(InForm As String, TblName As String, KeyField As String, KeyValue As Long) As String
    '==============================================
    ' Tham so dau vao:
    '   Inform: Cong thuc dau vao
    '   TblName: Ten bang chua du lieu
    '   KeyField: Ten truong khoa chua du lieu hien thoi
    '   KeyValue: Gia tri cua dong hien thoi
    '==============================================
    ' Tat nhien cach nay cu chuoi va ban can phai them reference cho DB vao DAO hoac ADODB (neu dung no thi sua lai cau
    ' truc truy van nhe. Va dac biet, toc do xu ly chac se rat rua.
    ' Nhung cung la mot cach thay the de giai quyet chuyen Query.
    
    Dim rs As Recordset, i As Long, theFomular As String
    theFomular = InForm
    ' Thuc hien Querry de lay gia tri truyen tham so cho cong thuc
    Set rs = CurrentDb.OpenRecordset("Select * from " & TblName & " where [" & KeyField & "] = " & KeyValue & ";")
    ' Duyet qua toan bo danh sach truong de giai quyet dut diem vu truyen tham so
    If rs.EOF Then GoTo Exit_Function
    For i = 0 To rs.Fields.Count - 1
        ' Neu cac ban muon lam cho CSDL nghiem tuc thi can dua them dau [] vao cong thuc vi rat co the
        ' se xay ra lam lan khi thay the, chang han truong 1 la a, truong an la nha thi no thay the se sai.
        ' vi the ban nen dung cach II cua toi thay vi cach 1 da comment
        ' I. 'theFomular = Replace(theFoular, rs.Fields(i).Name , rs.Fields(i))
        ' Neu dung cach tiep can duoi day thi trong cong thuc da phai co dau phan cach [] nhe
        theFomular = Replace(theFomular, "[" & rs.Fields(i).Name & "]", rs.Fields(i))
    Next
    ProcessFomulaX = Eval(theFomular)
Exit_Function:
    rs.Close
End Function
Hy vọng bài viết giúp ích được cho bạn!
 
Sửa lần cuối:
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
Giới thiệu với bạn cách tiếp cận có thay đổi chút ít từ tiếp cận ban đầu của tôi tại địa chỉ http://www.webketoan.vn/forum/showthread.php?t=50357.
Với cách này thì tuy tốc độ có chậm nhưng khắc phục được một số hạn chế khi đưa những phép toán phức tạp vào câu truy vấn.

Mã:
Function ProcessFomulaX(InForm As String, TblName As String, KeyField As String, KeyValue As Long) As String
    '==============================================
    ' Tham so dau vao:
    '   Inform: Cong thuc dau vao
    '   TblName: Ten bang chua du lieu
    '   KeyField: Ten truong khoa chua du lieu hien thoi
    '   KeyValue: Gia tri cua dong hien thoi
    '==============================================
    ' Tat nhien cach nay cu chuoi va ban can phai them reference cho DB vao DAO hoac ADODB (neu dung no thi sua lai cau
    ' truc truy van nhe. Va dac biet, toc do xu ly chac se rat rua.
    ' Nhung cung la mot cach thay the de giai quyet chuyen Query.
    
    Dim rs As Recordset, i As Long, theFomular As String
    theFomular = InForm
    ' Thuc hien Querry de lay gia tri truyen tham so cho cong thuc
    Set rs = CurrentDb.OpenRecordset("Select * from " & TblName & " where [" & KeyField & "] = " & KeyValue & ";")
    ' Duyet qua toan bo danh sach truong de giai quyet dut diem vu truyen tham so
    If rs.EOF Then GoTo Exit_Function
    For i = 0 To rs.Fields.Count - 1
        ' Neu cac ban muon lam cho CSDL nghiem tuc thi can dua them dau [] vao cong thuc vi rat co the
        ' se xay ra lam lan khi thay the, chang han truong 1 la a, truong an la nha thi no thay the se sai.
        ' vi the ban nen dung cach II cua toi thay vi cach 1 da comment
        ' I. 'theFomular = Replace(theFoular, rs.Fields(i).Name , rs.Fields(i))
        ' Neu dung cach tiep can duoi day thi trong cong thuc da phai co dau phan cach [] nhe
        theFomular = Replace(theFomular, "[" & rs.Fields(i).Name & "]", rs.Fields(i))
    Next
    ProcessFomulaX = Eval(theFomular)
Exit_Function:
    rs.Close
End Function
Hy vọng bài viết giúp ích được cho bạn!

Bác có thể bỏ chút thời gian giúp em vận dụng cụ thể vào file này không, cám ơn bác nhiều
http://webketoan.net/uploadfiles/nnz4oi17n2i326q.zip
 
paulsteigel

paulsteigel

Trung cấp
13/11/05
103
0
16
48
Hoà Bình
www.sfdp.net
Đây nhé, gửi bạn!
Bạn mở QryTest để xem. Chú ý tìm hiểu tại sao lại cần QryResults.
(Vì đây là QRY kết quả để giúp kiểm tra tên trường trong công thức).
 

Đính kèm

  • luong.rar
    18.1 KB · Lượt xem: 123
A

ahp

Guest
24/6/05
40
0
6
48
hanoi
Đây nhé, gửi bạn!
Bạn mở QryTest để xem. Chú ý tìm hiểu tại sao lại cần QryResults.
(Vì đây là QRY kết quả để giúp kiểm tra tên trường trong công thức).

Em đã hiều, rất cám ơn bác
 

Xem nhiều

Webketoan Zalo OA