Đánh giá chủ đề:
  • 1 Votes - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA
#31
(29-06-12, 11:48 AM)lehongduc Đã viết: Rất mong các Bạn tham gia trao đổi về chuyên đề này. Các Bạn có thể trao đổi về:
1. Nội dung bài viết, đúng, sai?
2. Những giải pháp khác của Bạn xung quanh vấn đề chúng ta đang bàn
3. Những thắc mắc phát sinh khi chạy file ứng dụng minh họa
Và những vấn đề có liên quan khác.
Thú thật, một mình độc thoại thấy cũng hơi vắng thiếu.

Mong các Bạn nhiệt tình tham gia trao đổi.

Hi, chào bạn Bài của bạn thật hay. Tôi có một vấn đề xin chi giáo
Giả sử tôi có file xml: <nvs><id>1</id><name>Nhan</name><id>1</id><name>Nhan</name></nvs>
Tôi viết một hàm sau
function LayDanhSach() as ADODB.recordset
end function
Bi giờ tôi muốn hiển thị trong form Access theo dang tabular thì đưa cái recordset này vào thế nào

Tôi đã làm như sau như bi lỗi error ở trường id

Private Sub Form_Load()
Dim rs As ADODB.Recordset
Set rs = mosNVXMLAdo.LayDanhSach
Set Me.Recordset = rs
End Sub

Mong bạn chỉ giáo!!1 thank
Chữ ký của tanthuc Xin chào, mình là tanthuc, Tham gia http://thuthuataccess.com/forum từ ngày 04-10 -12.
Reply
Những người đã cảm ơn bangnguyencong
#32
Vấn đề này hay đây. Tìm mãi mới thấy chủ đề này.
Bây giờ cũng khuya rồi, chưa kịp tìm hiểu kỷ bạn viết như thế nào. Nhưng đây là chủ đề tôi rất cần trong việc kết nối dữ liệu đã được upsite lên SQL và kết nối qua internet.
Đến bây giờ tôi đang bị bí về vụ này.
Rất hoan nghênh bạn Le Hong Duc.

Trân trọng!!!
034034034ClapClapClap
Chữ ký của bangnguyencong Hãy chia sẻ kinh nghiệm cùng mình trên ThuThuatAccess nhé! Chúc vui vẻ rose
Reply
Những người đã cảm ơn
#33
Chào bạn lehongduc!
Rất hoan nghênh và tôi rất quan tâm diễn đàn này.
Tôi đang xây dựng CSDL và phần mềm để lập hợp đồng xuất khẩu và theo dõi triển khai, thực hiện hợp đồng, thanh toán...
Tất cả đều trong tầm tay. Nhưng khó một cái là kết nối SQL và internet.
Công ty tôi có nhiều phòng ban. Trong đó có một văn phòng đại diện ở TP.HCM trong khi trụ sở chính tại Đồng Tháp. Nhưng tôi muốn cập nhật dữ liệu tập trung nên rất cần kết nối dữ liệu qua internet.
Nếu bạn giúp được điều này thì xin mời được hợp tác! Tất nhiên là phải có thù lao xứng đáng vì đây là công trình lớn mà.
Rất mong được phản hồi!
Trân trọng!
Chữ ký của bangnguyencong Hãy chia sẻ kinh nghiệm cùng mình trên ThuThuatAccess nhé! Chúc vui vẻ rose
Reply
Những người đã cảm ơn
#34
Xin hỏi bạn: Nếu để trường ngày tháng là Datetime thì có cách nào ấn định giá trị Null được không ?
Chữ ký của Minh Tiên -----------------------------------------------
Đường tuy ngắn, không đi không đến
Việc tuy nhỏ, không làm không nên.
                                           Tuân Tử
-----------------------------------------------
Reply
Những người đã cảm ơn
#35
bạn giúp minh chút nhé.làm sao để tìm đc giao điểm của 2 đồ thị trong access
Chữ ký của nguyenthanvu Xin chào, mình là nguyenthanvu, Tham gia http://thuthuataccess.com/forum từ ngày 12-02 -14.
Reply
Những người đã cảm ơn
#36
(30-11-12, 12:39 PM)bangnguyencong Đã viết: ....
Tất cả đều trong tầm tay. Nhưng khó một cái là kết nối SQL và internet.
...

Ngày nay, với sự phát triển của Internet, việc kết nối từ xa với lưu lượng trao đổi dữ liệu lớn không còn là vấn đề nữa. Với nhu cầu của bạn, có lẽ bạn chỉ cần nghiên cứu việc này:
1. Chỉnh đốn kết nối SQL cho đảm bảo như trong cùng mạng trước;
2. Xây dựng một kết nối VPN để các máy trạm kết nối vào mạng chứa máy chủ, sau đó các giao dịch sẽ được thực hiện một cách đơn giản như trong cùng một mạng.
Giải pháp thực hiện khá đơn giản, rất nhiều bộ định tuyến (Router) đều tích hợp sẵn VPN server (draytek, Cisco ...vv), tuy nhiên chúng có vẻ hơi đắt tiền một chút. Trong môi trường công ty, việc có một bộ định tuyến ổn định có tích hợp sẵn VPN server là điều cần thiết. Bạn có thể mua một trong các bộ định tuyến trên hoặc mua thiết bị Cisco tầm trung và cài lại firmware (hệ điều hành) sang DD-WRT cũng được. Hoặc cài một máy tính làm máy chủ kết nối VPN. Những việc này cần chuyên gia về mạng giúp đỡ, nếu bạn gặp khó khăn, có thể liên hệ với tôi. Tôi đã làm một số ứng dụng và thiết lập hệ thống như vậy.
Mỗi khi muốn cập nhập dữ liệu, chỉ cần kết nối VPN và mọi thứ sẽ được thực hiện như trong cùng 1 mạng.
Tất nhiên, yêu cầu là bạn phải có kết nối internet đủ mạnh tại 2 đầu, trong ví dụ này, khuyến nghị nên dùng cáp quang gói nhỏ nhất là đảm bảo.

Ngoài ra cũng còn một cách khác, bạn có thể thiết lập môi trường dữ liệu Web, tuy nhiên, việc này đỏi hỏi khá nhiều kinh nghiệm về lập trình web và khai thác số liệu web.
Chúc bạn thành công
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Che_Guevara
#37
Chào các Bạn,
Xin trao đổi thêm để các Bạn tiện tham khảo file ứng dụng làm mẫu minh hoạ tôi mới cập nhật.

1. Theo đề nghị của nhiều Bạn, tôi đã cho phục hồi file SQL Server database truy xuất được qua internet, đồng thời bổ sung thêm số lượng dữ liệu nhiều hơn trước để các Bạn có thể kiểm tra dễ dàng hơn.
Đồng thời tôi cũng đã chỉnh lý lại file minh hoạ cho dễ hiểu hơn theo yêu cầu của các Bạn. Xin mời đọc lại bài đầu của chuyên đề này để lấy link tải xuống file này.

2. Tôi đã chỉnh lý các form nhập dữ liệu với nội dung như sau:
- Chỉnh lý form frmContacts giúp cho việc tìm kiếm dữ liệu đã có được thuận tiện hơn.
Cách tìm kiếm như sau: khi muốn tìm dữ liệu theo 1 chi tiết thông tin nào đó ta chỉ cần nhập vào 1 vài ký tự có trong dòng thông tin đó (mà không cần nhập toàn bộ dòn thông tin cần tìm) tại ô tương ứng rồi bấm nút lệnh "Tìm kiếm"
Thí dụ: để tìm những khách hàng nào có địa chỉ ở tại "Cam Ranh" (có từ này trong dòng ghi địa chỉ) ta nhập từ "Cam Ranh" vào ô ghi địa chỉ rồi bấm nút lệnh tìm kiếm.
Code phục vụ cho việc tìm kiếm theo kiểu này như sau:
Trích dẫn:Function BuildSQLWhere(blnPriorWhere As Boolean, strPriorWhere As String, strValue As String, strDbFieldName As String) As String


On Error GoTo HandleError

Dim strWhere As String

If blnPriorWhere Then
'add to the existing where clause
strWhere = strPriorWhere & " AND "
Else
'create the where clause for the first time
strWhere = " WHERE "
End If

If strDbFieldName = "Ngaysinh" Then
strWhere = strWhere & strDbFieldName & " = '" & Format$(strValue, "dd-mmm-yy") & "' "
Else
'build where clause using LIKE so will find both exact
'matches and those that start with value input by user
If strDbFieldName = "Gioitinh" Then
strWhere = strWhere & strDbFieldName & " = " & PadQuotes(strValue) & " "
Else
strWhere = strWhere & strDbFieldName & " LIKE N'%" & PadQuotes(strValue) & "%' "
End If
End If

blnPriorWhere = True

'return where clause
BuildSQLWhere = strWhere

Exit Function


HandleError:
GeneralErrorHandler Err.Number, Err.Description, DB_QUANLY, "BuildSQLWhere"
Exit Function


End Function
Các Bạn chú ý đoạn code trên có dòng ghi:
Trích dẫn:strWhere = strWhere & strDbFieldName & " LIKE N'%" & PadQuotes(strValue) & "%' "
Đây là điều kiện lọc dữ liệu để tìm. Ta chú ý 2 dấu % đặt ở 2 đầu trong dòng trên có ý nghĩa "dữ liệu cần tìm bắt đầu và kết thúc bằng gì cũng được miễn là có sự hiện diện của từ được cung cấp bởi biến strValue là được".
Việc sử dụng ký tự % như vậy có khác với thông thường trong Access là hay dùng dấu ? hay *, đây chính là quy ước của câu lệnh SQL trong SQL Server. Ta phải viết theo đúng quy ước của SQL Server vì ứng dụng này chủ yếu là gửi các câu lệnh SQL truy xuất dữ liệu đến SQL Server.

- Chỉnh lý form nhập chứng từ nhập xuất phát sinh frmCtuNX:
+ Khi cần tìm chứng từ đã nhập theo số chứng từ: tại ô nhập số chứng từ (là kiểu comboBox) ta chỉ cần nhập 1 vài ký tự có trong số chứng từ đã nhập rồi bấm phím F4 sẽ được 1 danh sách sổ xuống liệt kê các số chứng từ có chứa ký tự đã nhập trong đó.
+ Khi cần chọn 1 khách hàng xác định: ta cũng làm tương tự tại ô khách hàng (cũng là 1 comboBox)
Vấn đề cần chú ý ở đây là ta đã cho hạn chế dữ liệu hiển thị trong các comboBox trong giới hạn vừa đủ với nhu cầu.

Còn nữa các Bạn ạ. Xin hẹn bài kế tiếp ta lại tiếp tục với những chú ý khi thiết kế form có subform theo dạng Unbound form thông qua form frmCtuNX vừa nêu ở trên.

Xin chào các Bạn,

Trong bài này xin trao đổi với các Bạn về thiết kế Unbound Form có chứa Subform. SubForm là Form nằm bên trong 1 Form khác.
Như tôi đã trao đổi tại bài #18, trái ngược với Bound Form luôn gắn liền với 1 nguồn dữ liệu xác định (được khai báo tại thuộc tính Record Source), Unbound Form là Form không gắn với một nguồn dữ liệu nào cả.
Đó chính là căn nguyên khiến 1 Unbound Form tránh được xung đột dữ liệu trong quá trình có nhiều người cùng truy xuất dư liệu, hoặc tuy chỉ có mỗi mình ên mần công chuyện với dữ liệu đó nhưng hổng dè đã “mở” nó ra mà quên “đóng” nó lại.
Những điều cần chú ý khi thiết kế 1 Unbound Form tôi đã trình bày tại #18, trong bài này chỉ tập trung vào việc thiết kế 1 Unbound Form nhưng lại có SubForm.
Một ví dụ điển hình cho nhu cầu này là thiết kế Form nhập chứng từ nhập xuất (dưới đây gọi là Main Form), với 1 Subform trình bày chi tiết các mặt hàng phát sinh.

1. Việc đầu tiên ta cần làm là làm sao để nạp thông tin của 1 chứng từ xác định xuống ô dữ liệu tương ứng trên Form khi cần (vì Unbound Form không duy trì thường trực 1 nguồn dữ liệu gắn kết với nó mà).
Đây chính là trường hợp ta cần làm việc với thông tin của 1 chứng từ xác định đã lập trước.
Trong file minh hoạ, công việc này được thực hiện thông qua các thủ tục:
+ LoadInvoiceInfoToForm: Nạp thông tin chứng từ lên Form
Trích dẫn:Sub LoadInvoiceInfoToForm(SoCtuSt, Optional NoSetSourceRecForSubForm)
Dim sqlSt As String, SQLrec As ADODB.Recordset
Dim KHrec As ADODB.Recordset
Dim tblName As String, MSKH, vIdKH As Long
‘Xác định nguồn dữ liệu chứa thông tin của chứng từ cần nạp
tblName = "tblctunx"
If IsNull(SoCtuSt) Then Exit Sub
sqlSt = "SELECT * FROM " & GetSchemaTable(tblName) & "." & tblName
sqlSt = sqlSt & " WHERE soctu ='" & SoCtuSt & "'"

Set SQLrec = ProcessRecordset(sqlSt)
'Nếu chứng từ hiện hữu, cho ghi thông tin chi tiết của chứng từ lên các ô dữ liệu tương ứng của Form
If SQLrec.RecordCount > 0 Then
Set objKhachHang = New clsDanhba
With Me
.txtId = SQLrec!id
.txtNgay = SQLrec!Ngay
.cmbNghiepvu = SQLrec!MSNV
.txtTsuat = SQLrec!tsuatvat
.txtNguoiGiaodich = SQLrec!NguoiGiaodich

MSKH = SQLrec!MSKH

sqlSt = "SELECT * FROM " & GetSchemaTable("tblDanhsach") & ".tblDanhsach"
sqlSt = sqlSt & " WHERE MSKH = '" & MSKH & "'"
Set KHrec = ProcessRecordset(sqlSt)
objKhachHang.PopulatePropertiesFromRecordset KHrec

.cmbKhachhang.RowSourceType = "Value List"
.cmbKhachhang.RowSource = objKhachHang.HoChulot & ";" & objKhachHang.MaKhachHang
.cmbKhachhang = objKhachHang.MaKhachHang

.txtDiachi = objKhachHang.Diachi
.txtPhone = objKhachHang.Dtvp
.txtMasoThue = objKhachHang.Msthue

KHrec.Close
Set KHrec = Nothing
' Và nạp nguồn dữ liệu chi tiết các mặt hàng phát sinh cho Subform
If IsMissing(NoSetSourceRecForSubForm) Then SetSourceRecForSubForm Me, "frmCtuNXCT"

End With
End If
'
SQLrec.Close
Set SQLrec = Nothing
End Sub

+ Để nạp nguồn dữ liệu chi tiết các mặt hàng phát sinh cho Subform ta dùng thủ tục SetSourceRecForSubForm
Trích dẫn:Sub SetSourceRecForSubForm(mForm As Form, sForm As String)
Dim sqlSt As String
Dim SQLrec As ADODB.Recordset
Dim tblName As String
Dim vSoCtu, stChema As String

vSoCtu = mForm!cmbSoCtu
‘Xác định nguồn dữ liệu chứa thông tin chi tiết hàng hoá phát sinh của chứng từ cần nạp
If Not IsNull(vSoCtu) Then
tblName = "tblctunxct"
stChema = GetSchemaTable(tblName)
sqlSt = "SELECT " & stChema & ".tbldmhanghoa.tenhanghoa, " & stChema & ".tblctunxct.*"
sqlSt = sqlSt & " FROM " & stChema & ".tbldmhanghoa INNER JOIN " & stChema & ".tblctunxct"
sqlSt = sqlSt & " ON " & stChema & ".tbldmhanghoa.mahang=" & stChema & ".tblctunxct.mahang"
sqlSt = sqlSt & " WHERE " & stChema & ".tblctunxct.soctu = '" & vSoCtu & "'"

Set SQLrec = ProcessRecordset(sqlSt)

Set mForm(sForm).Form.Recordset = SQLrec
‘Nạp thông tin chi tiết lên các ô dữ liệu tương ứng trên SubForm
With mForm(sForm).Form
.Requery
!txtId.ControlSource = "id"
!txtMahang.ControlSource = "mahang"
!txtTenHanghoa.ControlSource = "tenhanghoa"
!txtCapDvt.ControlSource = "dvt"
!txtDvt.ControlSource = "=IIF(not isnull(dvt),flookup('kihieu','tbldonvitinh','cap=' & [dvt]),'')"
!txtSoluong.ControlSource = "soluong"
!txtDongia.ControlSource = "dongia"
!chkCKTL.ControlSource = "lacktyle"
!txtMucCK.ControlSource = "mucck"
End With
SQLrec.Close
Set SQLrec = Nothing
End If
End Sub

Như vậy, khi ta chọn 1 số chứng từ xác định, ứng dụng sẽ cho chạy các thủ tục nêu trên để nạp nguồn dữ liệu tương ứng cho Main Form và SubForm.
Ta gán các thủ tục cần thực hiện với sự kiện ngay sau khi số chứng từ được cập nhật (cmbSoCtu_AfterUpdate)
Trích dẫn:Private Sub cmbSoCtu_AfterUpdate()
Dim vSoCtu
ClearInputCTHH ‘Xoá trống các ô nhập chi tiết hàng hoá
vSoCtu = Trim(Me.cmbSoCtu.Text)
LoadInvoiceInfoToForm vSoCtu ‘Nạp thông tin chứng từ đã chọn lên MainForm và SubForm
End Sub

Vậy khi cần hiệu chỉnh chi tiết chứng từ đã lập và đang hiển thị trên Form thì làm sao?
Thật đơn giản các Bạn ạ:
+ Đối với thông tin là chi tiết hàng hoá phát sinh: ta chỉ cần chuyển con trỏ đến dòng ghi mặt hàng cần hiệu chỉnh là ứng dụng sẽ copy các thông tin đó lên các ô có nền sẩm màu sẵn sàng cho ta hiệu chỉnh (hoặc xoá). Hiệu chỉnh xong ta bấm nút lệnh ghi bên phải (có hình chiếc đĩa mềm) để cho ghi lại nội dung vừa ddiiefu chỉnh.
Việc này được thực hiện thông qua thủ tục SaveToInvoiceDetailFromForm
Trích dẫn:Sub SaveToInvoiceDetailFromForm(Optional InVoiceDetailId)
'Luu thong tin tren form vao tblctunxCT
'UpdateInvoiceDetail
On Error GoTo HandleError

Dim sqlSt As String, tblName As String
Dim vId
Dim MucCK As Double, CKTL As Byte

Call OpenMyConnection

tblName = "tblctunxct"
With Me
vId = Me.txtDetailId
MucCK = Nz(.txtMucCK)
If IsNull(.chkCKTL) Then
CKTL = 0
Else
If .chkCKTL.Value = True Then
CKTL = 1
Else
CKTL = 0
End If
End If
‘Phân biệt là trường hợp nhập mới hay hiệu chỉnh lại dữ liệu đã có.
If Not IsNull(vId) Then
sqlSt = "UPDATE " & GetSchemaTable(tblName) & "." & tblName & " SET "
sqlSt = sqlSt & " soctu ='" & Trim(.cmbSoCtu) & "',"
sqlSt = sqlSt & " mahang ='" & .cmbMSHH & "',"
sqlSt = sqlSt & " dvt =" & .cmbDvt & ","
sqlSt = sqlSt & " soluong =" & .txtSoluong & ","
sqlSt = sqlSt & " dongia =" & .txtDongia & ","
sqlSt = sqlSt & " lacktyle =" & CKTL & ","
sqlSt = sqlSt & " mucck =" & MucCK
sqlSt = sqlSt & " WHERE ("
sqlSt = sqlSt & " soctu='" & Trim(Me.cmbSoCtu) & "'"
sqlSt = sqlSt & " AND id=" & InVoiceDetailId
sqlSt = sqlSt & ")"
Else
sqlSt = "INSERT INTO " & GetSchemaTable(tblName) & "." & tblName
sqlSt = sqlSt & "(soctu, mahang, dvt, soluong, dongia, lacktyle, mucck)"
sqlSt = sqlSt & " VALUES ("
sqlSt = sqlSt & " '" & Trim(.cmbSoCtu) & "',"
sqlSt = sqlSt & " '" & .cmbMSHH & "',"
sqlSt = sqlSt & " " & .cmbDvt & ","
sqlSt = sqlSt & " " & .txtSoluong & ","
sqlSt = sqlSt & " " & .txtDongia & ","
sqlSt = sqlSt & " " & CKTL & ","
sqlSt = sqlSt & " " & Nz(MucCK)
sqlSt = sqlSt & ")"
End If
End With


MyConn.Execute sqlSt

Call CloseMyConnection ‘Dùng xong rồi thì đóng lại cho đỡ tốn tài nguyên và khỏi gặp xung đột dữ liệu đó các Bạn.

HandleError:
If Err > 0 Then
GeneralErrorHandler Err.Number, Err.Description, NhapXuat_FORM, "SaveToInvoiceDetailFromForm"
Exit Sub
End If
End Sub
Ở đây chúng ta chú ý: có 2 trường hợp cần phân biệt là nhập mới và hiệu chỉnh thông tin đang có.
Xem trong thủ tục trên chúng ta thấy thủ tục có phân biệt 2 trường hợp này bằng cách xet giá trị của ô txtDetailId, đây là ô chứa giá trị Id của chi tiết hàng hoá phát sinh. Trong thiết kế, ta cho ô này ẩn đi (bằng cách khai báo thuộc tính Visible = False). Nếu ô này có chứa nội dung xác định thì là trường hợp hiệu chỉnh dữ liệu đang có, ngược lại nếu nó rổng không (IsNull) là trường hợp nhập mới.
Trường hợp muốn xoá dòng ghi chi tiết hàng phát sinh xác định: ta cho nạp dòng ghi chi tiết hàng hoá đó lên các ô sẩm màu rồi bấm nút lệnh Xoá (có hình gạch chéo) nằm bên trái dòng của các ô sẩm màu này.
Thủ tục tương ứng như sau:
Trích dẫn:Dim vHoi As Long, sqlSt As String, tblName As String
Dim DetailId
DetailId = Me.txtDetailId
If Not IsNull(DetailId) Then
vHoi = Eval("msgbox('" & "Ban vua ra lenh cho xoa dong ghi mat hang nay" & vbCrLf & "Co phai Ban chac chan muon Xoa hay khong?" & "@" & "Bam YES de xoa, bam NO de huy bo lenh nay" & "@" & "',36,'Xoa chi tiet hang hoa')")
If vHoi = vbYes Then
tblName = "tblctunxct"
sqlSt = "DELETE " & GetSchemaTable(tblName) & "." & tblName
sqlSt = sqlSt & " WHERE Id =" & DetailId
'
Call OpenDbConnection
ExecuteSQLCommand sqlSt
Call CloseDbConnection
'Xoá xong thì cho cập nhật lại nội dung hiển thị trên SubForm
SetSourceRecForSubForm Me, "frmCtuNXCT"
End If
End If
+ Đối với thông tin chung của chứng từ: cũng tương tự như trên, ta hiệu chỉnh thông tin tại các ô tương ứng; và cũng phân biệt 2 trường hợp: nhập mới và hiệu chỉnh thông tin đang có. Việc ghi lại các thông tin đã cập nhật vào bảng dữ liệu ghi chứng từ phát sinh được thực hiện bằng thủ tục SaveToInvoiceFromForm
Trích dẫn:Sub SaveToInvoiceFromForm(Optional InvoiceId, Optional NoLoadInfo)
'Luu thong tin tren form vao tblctunx

'UpdateOrInsert:
'+ True: Luu thong tin thay doi vao mau tin dang hien huu
'+ Flase: Them mau tin moi

'InvoiceId: so chung tu
'
On Error GoTo HandleError

Dim sqlSt As String, tblName As String
Dim vId

Call OpenMyConnection

tblName = "tblctunx"

With Me
vId = Me.txtId
If Not IsNull(vId) Then
If IsNull(InvoiceId) Then Exit Sub
sqlSt = "UPDATE " & GetSchemaTable(tblName) & "." & tblName & " SET "
sqlSt = sqlSt & " soctu ='" & .cmbSoCtu & "',"
sqlSt = sqlSt & " ngay ='" & Format$(.txtNgay, "dd-mmm-yy") & "',"
sqlSt = sqlSt & " msnv ='" & .cmbNghiepvu & "',"
sqlSt = sqlSt & " mskh ='" & .cmbKhachhang & "'"
If Not IsNull(.txtNguoiGiaodich) Then sqlSt = sqlSt & ", nguoigiaodich ='" & .txtNguoiGiaodich & "'"
If Not IsNull(.txtTsuat) Then sqlSt = sqlSt & ", tsuatvat =" & .txtTsuat
sqlSt = sqlSt & " WHERE ("
sqlSt = sqlSt & " soctu='" & InvoiceId & "'"
sqlSt = sqlSt & ")"

Else
If IsNull(.cmbSoCtu) Then Exit Sub
sqlSt = "INSERT INTO " & GetSchemaTable(tblName) & "." & tblName
sqlSt = sqlSt & "(soctu, ngay, msnv, mskh"
If Not IsNull(.txtNguoiGiaodich) Then sqlSt = sqlSt & ", nguoigiaodich"
If Not IsNull(.txtTsuat) Then sqlSt = sqlSt & ", tsuatvat"
sqlSt = sqlSt & ")"
sqlSt = sqlSt & " VALUES ("
sqlSt = sqlSt & " '" & .cmbSoCtu & "',"
sqlSt = sqlSt & " '" & Format$(.txtNgay, "dd-mmm-yy") & "',"
sqlSt = sqlSt & " '" & .cmbNghiepvu & "',"
sqlSt = sqlSt & " '" & .cmbKhachhang & "'"
If Not IsNull(.txtNguoiGiaodich) Then sqlSt = sqlSt & ", '" & .txtNguoiGiaodich & "'"
If Not IsNull(.txtTsuat) Then sqlSt = sqlSt & ", " & .txtTsuat
sqlSt = sqlSt & ")"
End If
End With

MyConn.Execute sqlSt

‘Lưu xong thì cho cập nhật lại các thông tin đã lưu lên Form.
If IsMissing(NoLoadInfo) Then
LoadInvoiceInfoToForm Me.cmbSoCtu
Else
LoadInvoiceInfoToForm Me.cmbSoCtu, True
End If

Call CloseMyConnection ‘Mở ra xài xong thì đóng lại

HandleError:
If Err > 0 Then
GeneralErrorHandler Err.Number, Err.Description, NhapXuat_FORM, "SaveToInvoiceFromForm"
Exit Sub
End If
End Sub
Trong thủ tục trên ta chú ý đoạn
Trích dẫn:If IsMissing(NoLoadInfo) Then
LoadInvoiceInfoToForm Me.cmbSoCtu
Else
LoadInvoiceInfoToForm Me.cmbSoCtu, True
End If
Cho Lưu xong thì cho cập nhật lại các thông tin đã lưu lên Form. Cái này cần để ghi bổ sung những thông tin chỉ phát sinh khi dữ liệu được ghi vào bảng dữ liệu, chẳng hạn như chỉ số Id tự động của bản ghi, hoặc các giá trị tính toán cần thiết khác.
Khi ghi dữ liệu vào bảng dữ liệu, chúng ta cần chú ý đến 1 thực tế là có những thông tin chi tiết của chứng từ không nhất thiết lúc nào cũng có. Do vậy khi ta viết các thủ tục cập nhật phải chú ý đến các trường hợp này. Các Bạn có thể thấy điều này được thể hiện ở những dòng sau đây trong thủ tục nêu trên:
Trích dẫn:If Not IsNull(.txtNguoiGiaodich) Then sqlSt = sqlSt & ", '" & .txtNguoiGiaodich & "'"
If Not IsNull(.txtTsuat) Then sqlSt = sqlSt & ", " & .txtTsuat
Ở đây tôi xác định các chi tiết: Người trực tiếp giao dịch, thuế suất VAT là những chi tiết thông tin không phải lúc nào cũng bắt buộc phải có khi lập chứng từ nên đã dự liệu bằng các statement IF... THEN ...

Bài đã dài. Xin hẹn các Bạn trong bài sau.
Chữ ký của lehongduc Lê Hồng Đức
Số ĐT: 0913.941.144
Email: lhongduc@gmail.com, lehongduc@ymail.com
Website: http://quantribanhang.vn
Reply
Những người đã cảm ơn paulsteigel , Minh Tiên , Noname , MatTroiNguQuen , quanghoasla , maidinhdan
#38
Chào các Bạn,
Có Bạn vừa gửi email cho tôi góp ý rằng sao ta không phát triển thủ tục SetSourceRecForSubForm lên để áp dụng cho việc nạp RecordSource cho subform trong mọi trường hợp, chứ không phải chỉ riêng cho 1 trường hợp như tôi đã làm.
Đây là một góp ý rất chí lý. Vậy xin mời các Bạn tham gia viết lại thủ tục SetSourceRecForSubForm theo hướng phát triển được đề nghị nêu trên.
Chữ ký của lehongduc Lê Hồng Đức
Số ĐT: 0913.941.144
Email: lhongduc@gmail.com, lehongduc@ymail.com
Website: http://quantribanhang.vn
Reply
Những người đã cảm ơn Noname
#39
(05-07-12, 02:14 PM)Noname Đã viết:
(05-07-12, 12:27 PM)lehongduc Đã viết: Chào các Bạn,

Hôm nay, xin trao đổi với các Bạn về Bound Form và UnBound Form

1. Bound Form là gì?
Bound Form là 1 form được gán Record Source xác định,
............
2. UnBound Form là gì?
Ngược với Bound Form, UnBound Form là form không gắn với 1 nguồn dữ liệu xác định nào cả.
.....
3. Vậy, nên áp dụng Bound Form hay UnBound Form? Cái nào ưu việt hơn?
Câu trả lời ở đây là: lựa chọn phải tùy vào mục đích ta áp dụng để làm gì và trong hoàn cảnh cụ thể như thế nào?
Nếu chỉ với dữ liệu chạy cục bộ, chỉ có một người sử dụng trong cùng 1 thời gian và quy mô dữ liệu không lớn lắm thì lựa chọn áp dung Bound Form sẽ tốt hơn, vì dễ dàng và nhanh chóng.
Cái nào ưu việt hơn? cái nào giúp ta đạt được mục đích với chi phí ít nhất (tiền bạc, thời gian, công sức) là cái ưu việt hơn. Ở đây chúng ta cần suy niệm nguyên tắc của tiền nhân là “đừng bao giờ mổ gà bằng dao mổ trâu và ngược lại.”
Bài viết rất hay và câu nói rất chí lý! Mình thấy nhiều bạn cứ cố nhét thật nhiều VBA vào để có vẻ 'pro', nhưng thật ra chỉ vài câu query là giải quyết được vấn đề.Mình từng thấy 1 chương trình kế toán chỉ có code đọc số thành chữ là dùng VBA, còn lại toàn query và macro và "10 năm vẫn chạy tốt". Và cũng đúng như bạn phân tích, unbound đúng là xử lý tốt hơn Bound, nhưng các bạn cần cân nhắc hiệu quả kinh tế khi dùng nó!

Thank các anh/ chị đã chia sẻ các bài viết này. Bài viết với kiến thức sâu và rộng. Nếu được mô tả trực quan sinh động bằng video thì quả thật là tuyệt vời hơn.
Qua bài viết này có câu nói rất tuyệt:(Ở đây chúng ta cần suy niệm nguyên tắc của tiền nhân là “đừng bao giờ mổ gà bằng dao mổ trâu và ngược lại.”). Hãy làm điều đơn giản nhưng hiệu quả dù dùng phương pháp nào, cách nào cũng được miễn là người đó có sở trường về cái mình đã biết. cách nào đơn giản và hiệu quả thì mình chọn.nhưng tựu lại là vẫn đạt được cái đích tới của mình.
Chữ ký của quanghoasla Hãy chia sẻ kinh nghiệm cùng mình trênThuThuatAccess nhé! Chúc vui vẻ rose
My site: My site hoặc My site
ღღღღღTài sản của quanghoasla (View All Items) ღღღღღ
Reply
Những người đã cảm ơn
#40
(09-07-12, 01:22 PM)lehongduc Đã viết: Chào các Bạn,

Về việc kết nối với dữ liệu nguồn qua mạng máy tính tôi thấy cũng cần trao đổi thêm về việc tổ chức dữ liệu sao cho việc kết nối dữ liệu được thuận lợi và hiệu quả nhất.

Theo tôi thấy (có thể các Bạn sẽ thấy khác): Trong thực tế, không phải lúc nào chúng ta cũng cần lấy dữ liệu xuống bằng cách kết nối với dữ liệu nguồn đặt tại server; có những nguồn dữ liệu có tính ổn định nhất định (không bị thay đổi thường xuyên) ta có thể cho trích xuất với phạm vi giới hạn nhất định và cho lưu xuống máy client (máy khách cần kết nối vào server), sau đó ta sẽ cho nạp nguồn dữ liệu từ dữ liệu đã được trích xuất này. Làm như vậy ta vừa cải thiện được tốc độ truy xuất dữ liệu, vừa giảm được tải không cần thiết cho cả server và client.

Các Bạn thử xem xét tình huống sau đây nhé:
Với doanh nghiệp bán hàng trên phạm vi rộng, có ứng dụng chạy trên client kết nối đến dữ liệu nguồn ở server, ứng dụng này dành cho các nhân viên thị trường sử dụng trên các laptop để thực hiện nhiệm vụ "Tìm kiếm khách mua hàng và lập đơn đặt hàng theo bảng giá ấn định chung". Mỗi nhân viên thị trường đều được phân công phụ trách một phạm vi địa lý nhất định.

Như vậy, ta có thể cho trích xuất các nguồn dữ liệu sau lưu xuống máy client để ứng dụng client sử dụng trực tiếp, không cần phải lấy từ server thông qua kết nối qua mạng:
+ Danh sách khách hàng trong phạm vi địa lý đã phân công cho từng nhân viên;
+ Danh mục hàng hoá (có bảng giá) cũng trong giới hạn cần thiết.

Đồng thời với đó, ta sẽ có các thủ tục thích hợp để cho đồng bộ dữ liệu đang lưu tạm trên các máy Client với dữ liệu gốc trên server. Việc đồng bộ dữ liệu này sẽ được thực hiện tại thời điểm thích hợp (trong ngày hoặc trong tuần) hoặc khi có sự kiện thay đổi dữ liệu xảy ra (như đơn giá được người có thẩm quyền cập nhật mới, ...).

Các Bạn có thấy điều gì không ổn trong đề nghị trên của tôi không? Xin vui lòng góp ý trao đổi thêm.

Theo dõi các bài viết của anh rất hay nhưng chủ yếu bằng vb code thôi. Có điều em chưa rõ lắm trong việc kết nối dữu liêu. Nếu đơn giản hóa việc kết nối data có thể hiểu như sau:
1- kết nối dữ liệu từ 1 client đến 1 host " cái này mua của nhà cung cấp dịch vụ host cũng được?
2- Kết nối dữ liều từ 1 client đến 1 máy chủ tại cơ quan.

Nhưng tựu chung lại em có 3 câu hỏi để hiểu rõ được cách thức kết nối dữ liệu thông qua sql server.

câu 1: Em có phải cài đặt sql server để chạy app?

câu2: Nếu đặt database.mdb trên 1 máy chủ có nhất thiết cài thêm iss? đây là 1 tất yếu để có localhost trên 1 máy server?

cau 3; Anh có thể demo video kết nối qua video cho anh/ em view trực quan sinh động hơn 1 chút được không?

Xin cảm ơn sự chia sẻ nhiệt tình với kiến thức sâu của anh cho diễn đàn. Hầu như đa số đông đang mắc ở việc kết nối data.mdb qua sql server để chỉnh chu hơn. nâng cao hiệu xuất hơn trong việc bảo mật, chia sẻ tài nguyên online. Và tăng tính mềm, dẻo, linh hoạt đối với lập trình app trên nền ms office.
Em Rất mong sự phản hồi của anh sớm. Lightbulb
Chữ ký của quanghoasla Hãy chia sẻ kinh nghiệm cùng mình trênThuThuatAccess nhé! Chúc vui vẻ rose
My site: My site hoặc My site
ღღღღღTài sản của quanghoasla (View All Items) ღღღღღ
Reply
Những người đã cảm ơn


Có thể liên quan đến chủ đề
Chủ đề: Tác giả Trả lời: Xem: Bài mới nhất
Question [Help] Link tất các table trong một file.mdb bằng VBA MinhnHang 7 176 Hôm qua, 11:59 AM
Bài mới nhất: maidinhdan
  [Thủ Thuật] Tìm số thứ tự bị thiếu trong dãy toanle 8 203 07-12-16, 02:25 PM
Bài mới nhất: toanle
  Sựa khác nhau giữa Module và Class Module, phạm vi áp dụng của từng loại. MinhnHang 6 303 29-11-16, 09:11 PM
Bài mới nhất: ongke0711
  Tránh xung đột dữ liệu trong access quocdung9999 16 1,692 23-11-16, 11:13 AM
Bài mới nhất: quocdung9999
  [Hỏi] Kết nối nhiều lần hay kết nối 1 lần trong ADO ưu điểm hơn Minh Tiên 1 123 10-11-16, 10:41 AM
Bài mới nhất: maidinhdan

Chuyển nhanh:


User(s) browsing this thread: 1 Guest(s)
Diễn Đàn Thơ Văn Thi Ẩm Lâu|Nhà Hàng Sông Thơ