• Tạo Report theo dạng crosstab Query
  • Tạo Report theo dạng crosstab Query

    thunga25 > 01-09-15, 02:29 PM

    Chào các bạn, mình đang muốn làm 1 report để so sánh báo giá giữa các nhà cung cấp theo từng mặt hàng, theo dạng crosstab.
    Đây là dạng report mình muốn: [Hình: BC.jpg]

    http://www.mediafire.com/view/xh241u0k7do7qyc/BC.jpg

    Đây là CSDL:  
    http://www.mediafire.com/download/grdmtj...BAOCAO.mdb

    Bạn nào biết thì chỉ mình với, vì mình đang cần gấp, nhưng tìm mãi vẫn chưa biết cách.
  • RE: Tạo Report theo dạng crosstab Query

    tranthanhan1962 > 01-09-15, 05:35 PM

    (01-09-15, 02:29 PM)thunga25 Đã viết: Chào các bạn, mình đang muốn làm 1 report để so sánh báo giá giữa các nhà cung cấp theo từng mặt hàng, theo dạng crosstab.
    Đây là dạng report mình muốn: [Hình: BC.jpg]

    http://www.mediafire.com/view/xh241u0k7do7qyc/BC.jpg

    Đây là CSDL:  
    http://www.mediafire.com/download/grdmtj...BAOCAO.mdb

    Bạn nào biết thì chỉ mình với, vì mình đang cần gấp, nhưng tìm mãi vẫn chưa biết cách.

    Của bạn đây
  • RE: Tạo Report theo dạng crosstab Query

    paulsteigel > 01-09-15, 05:44 PM

    Thế là cụ tranthanhnhan đã giả nhời rồi. em cắm cúi post mà không biết.
    Thôi thì bổ sung với một bài nữa vậy ạ

    (01-09-15, 02:29 PM)thunga25 Đã viết: ....
    Bạn nào biết thì chỉ mình với, vì mình đang cần gấp, nhưng tìm mãi vẫn chưa biết cách.

    Bài của bạn có mấy vấn đề sau:
    1. CSLD của bạn thiết kế chưa chuẩn mực
    + bạn cần để chế độ Compact khi đóng csdl để nó đỡ phình to (nhấn Tool/Options/General - chọn Compact on Close)
    + Bảng Test của bạn chưa đáp ứng chuẩn Nomalize vì bạn để 2 trường Mã NCC và Tên dạng text lưu kèm số liệu. Cái này làm cho csdl to lên và khó quản lý.
    + Query crosstab của bạn thiết kế không đúng, chỉ cần Column Heading là Mã Nhà cung cấp hoặc tên còn phần rowheading với mã nhà cung cấp thì bỏ đi
    + Trường đơn giá phải có kiểu số liệu là Number/Double hoặc single nhé, không để kiểu text được.
    2. Cách sửa chữa như sau
    + Sửa lại thiết kế bảng, tạo một bảng tblNCC trong đó như file đính kèm.
    Người ta quản lý danh mục ncc dựa vào ID
    + Bảng test sửa lại, liên kết với bảng nhà cung cấp bằng 1 trường ID_NCC là xong, kiểu số.

    3. Về vấn đề crosstab.
    Do số lượng nhà cung cấp là bất định vì thế nó có thể lên đến hàng ngàn. Như vậy bạn phải giới hạn số nhà cung cấp hiển thị trong báo cáo. Muốn như vậy thì cần đưa ra tiêu chí lựa chọn số nhà cung cấp cần hiển thị, ví dụ tối đa là bao nhiêu (chẳng hạn 10) vì khổ giấy A4 chỉ cho in đến thế.
    Sau đó sẽ tiếp tục in tiếp với các nhà cung cấp khác.

    Giải pháp đưa vào báo cáo.
    1. Thiết kế 1 báo cáo chuẩn với các trường chuẩn hiển thị tên hàng, còn lại là khoảng 10 textbox/label rỗng có tên theo chuẩn chẳng hạn
    lb1, lb2 ...lb10, txt1, txt2 ...txt10.

    2. Thiết kế thủ tục nạp thông tin cho các txt và lbl dựa vào các trường hiển thị trong crosstab query.
    Thủ tục này phải đặt trong mục Report_Open.
    các thứ như sau:
    Truy vấn crosstab qry_price_compare (đã được sửa lại) làm nguồn cho báo cáo
    ... bạn có thể xem thêm đoạn code

    Mã:
    Private Sub Report_Open(Cancel As Integer)
        ' Thu tuc de dua so lieu vao bao cao va dieu chinh ten cot
        Dim SqlStr As String
        Dim rs As Recordset
        Dim iCol As Long, i As Long
        SqlStr = "Select * from " & Me.RecordSource & ";"
        Set rs = CurrentDb.OpenRecordset(SqlStr)
        ' Cot 1 luon la ten hang, bat dau tu cot 2 se la ma nha cung cap
        With Me
            For i = 1 To rs.Fields.Count - 1
                .Controls("lbl_cr_" & i).Visible = True
                .Controls("lbl_cr_" & i).Caption = GetColumnName(Val(rs.Fields(i).Name))
                ' doi voi textbox thi dat ten vung so lieu luon
                ' vi ten textbox la so nen phai co them ham chuyen gia tri sang chu
                .Controls(CStr(i)).Visible = True
                .Controls(CStr(i)).ControlSource = rs.Fields(i).Name
                ' dinh dang so lieu
                .Controls(CStr(i)).Format = "Standard"
                .Controls(CStr(i)).DecimalPlaces = 0
            Next
            ' Cac doi tuong khac thi giau di
            While i <= 9
                .Controls("lbl_cr_" & i).Visible = False
                ' doi voi textbox thi dat ten vung so lieu luon
                .Controls(CStr(i)).Visible = False
                i = i + 1
            Wend
        End With
        rs.Close
        DoCmd.Maximize
    End Sub

    Tôi cũng bổ sung công cụ vẽ đường kẻ trong báo cáo. bạn chỉ cần gọi thủ tục như trong báo cáo. Khi thiết kế cần có một nhãn là lb1 nằm ở ngoài cùng bên trái làm điểm chuẩn canh lề.
    Các nhãn dùng làm chuẩn để kẻ dòng đều phải được đặt tag là 1

    Đường link bài đây nhé
    http://www.sfdp.net/thuthuataccess/minhh...BAOCAO.rar
  • RE: Tạo Report theo dạng crosstab Query

    ongke0711 > 01-09-15, 08:20 PM

    Bác paulsteigel cho hỏi: công cụ vẽ đường kẻ trong report của bác sẽ có lợi ích gì hơn so với vẽ tay bằng line vậy?
  • RE: Tạo Report theo dạng crosstab Query

    paulsteigel > 01-09-15, 09:14 PM

    (01-09-15, 08:20 PM)ongke0711 Đã viết: Bác paulsteigel cho hỏi: công cụ vẽ đường kẻ trong report của bác sẽ có lợi ích gì hơn so với vẽ tay bằng line vậy?
    Công cụ vẽ lưới nhìn chung là khá tiện lợi với mình vì phải dùng nhiều loại báo cáo phức tạp, nếu căn chỉnh bằng tay sẽ mất nhiều thời gian thay vào đó mình chỉ cần vẽ một vài nhãn, định kích thước ổn thế là nó vẽ ra cho mình theo yêu cầu. Kể cả trong trường hợp dòng co dãn. Cái này thì thích hợp với ai phải vẽ nhiều báo cáo, mình giới thiệu để xem ai có ứng dụng được không mà thôi.
    Để dùng được công cụ này.
    Bước 1: 
    + Vẽ các Label tiêu đề và đặt Tag là 1
    + Bước 2 đặt tên 1 label là lb1 ở bên trái trong cùng làm chuẩn.

    Bước 2:
    Đặt sự kiện On Print và dán vào dòng lệnh sau
    * Để vẽ tiêu đề theo đúng kích thước các label và không vẽ dòng dọc ra toàn tiêu đề
    If PrintCount = 1 Then DrawGrid Me
    * Để vẽ ô lưới với các dòng dọc trùm hoàn toàn tiêu đề
    If PrintCount = 1 Then DrawGrid Me, , False

    Đơn giản thế thôi
    Sau đây là vài mẫu báo cáo mình vẽ bằng cái này
  • RE: Tạo Report theo dạng crosstab Query

    thunga25 > 02-09-15, 02:18 PM

    (01-09-15, 05:35 PM)tranthanhan1962 Đã viết:
    (01-09-15, 02:29 PM)thunga25 Đã viết: Chào các bạn, mình đang muốn làm 1 report để so sánh báo giá giữa các nhà cung cấp theo từng mặt hàng, theo dạng crosstab.
    Đây là dạng report mình muốn: [Hình: BC.jpg]

    http://www.mediafire.com/view/xh241u0k7do7qyc/BC.jpg

    Đây là CSDL:  
    http://www.mediafire.com/download/grdmtj...BAOCAO.mdb

    Bạn nào biết thì chỉ mình với, vì mình đang cần gấp, nhưng tìm mãi vẫn chưa biết cách.

    Của bạn đây
     
    em đã xem bài của anh, nhưng hình như là nó không thay đổi khi nhà cc thay đổi thì phải, ví như có lúc có 1 nhà cung cấp, có khi có 2 hoặc 4 thì bài này không được phải không anh?
  • RE: Tạo Report theo dạng crosstab Query

    thunga25 > 02-09-15, 02:20 PM

    (01-09-15, 05:44 PM)paulsteigel Đã viết: Thế là cụ tranthanhnhan đã giả nhời rồi. em cắm cúi post mà không biết.
    Thôi thì bổ sung với một bài nữa vậy ạ


    ...............
    Đường link bài đây nhé
    http://www.sfdp.net/thuthuataccess/minhh...BAOCAO.rar

    Cảm ơn bạn nhiều nhé mình thấy bài của bạn có thể tùy biến được số nhà cung cấp rất hay, để mình xem có gì không hiều thì cho mình hỏi với nhé.
  • RE: Tạo Report theo dạng crosstab Query

    tranthanhan1962 > 02-09-15, 11:36 PM

    (02-09-15, 02:18 PM)thunga25 Đã viết: em đã xem bài của anh, nhưng hình như là nó không thay đổi khi nhà cc thay đổi thì phải, ví như có lúc có 1 nhà cung cấp, có khi có 2 hoặc 4 thì bài này không được phải không anh?

    Do bạn nói gấp cho nên mình xử lý nhanh cho bạn. Mình có chừa mấy ô trống để bạn thêm control source theo đúng số lượng NCC của bạn. Nhưng nếu bạn muốn tùy biến thì lại là vấn đề khác.
    1/ Bạn có thể xử lý theo bạn paulsteigel bằng VBA
    2/ Bạn có thể thay thế Crosstab Query R_SO_SANH_GIA bằng 1 select query lên kết R_SO_SANH_GIA_01. Để tạo sẳn một query nhiều dự trù nhiều field NCC (Chắc chắn rằng số lượng field tên NCC được thiết đặt sẳn lớn hơn Số lượng NCC sẽ có). Làm cách này khỏi phải viết code VBA.
    Có nhiều phương pháp để xử lý ra một kết quả. Tùy cách bạn chọn cho phù hợp
    Cách 2
  • RE: Tạo Report theo dạng crosstab Query

    thunga25 > 05-09-15, 02:24 PM

    (01-09-15, 05:44 PM)paulsteigel Đã viết: ...............
    Đường link bài đây nhé
    http://www.sfdp.net/thuthuataccess/minhh...BAOCAO.rar

    Bạn paulsteigel ơi cho mình hỏi với, mình đã đổi CSDL lại giống bạn nói và OK rồi, nhưng mình muốn cái qry_price_compare có thêm trường Ma_DDH_TV, đây là mã đơn đặt hàng, để khi tạo báo cáo so sánh báo giá thì đưa ra những mặt hàng của đơn này thôi(tức là khi chọn mã này thì xuất ra được báo cáo so sánh đơn giá theo Ma_DDHTV). Nhưng khi mình thêm Ma_DDH_TV vào thì  bị lỗi ở :GetColumnName = DLookup("Ten_NCC","Ma_DDHTV", "T_NCC", "Ma_NCC=" & fldName).
  • RE: Tạo Report theo dạng crosstab Query

    paulsteigel > 05-09-15, 05:06 PM

    Bạn sửa lại thủ tục trong sự kiện report_open như code dưới đây.
    Query của bạn cũng sửa với trường Ma_DDHTV là Groupby và Rowheading.
    Nếu bạn muốn lọc theo trường này thì đơn giản là khi gọi báo cáo chỉ cần đặt thêm lọc với điều kiện WHERE Ma_DDHTV='xxx' là xong
    Mã:
    Private Sub Report_Open(Cancel As Integer)
        ' Thu tuc de dua so lieu vao bao cao va dieu chinh ten cot
        Dim SqlStr As String
        Dim rs As Recordset
        Dim iCol As Long, i As Long, j As Long
        SqlStr = "Select * from " & Me.RecordSource & ";"
        Set rs = CurrentDb.OpenRecordset(SqlStr)
        ' Cot 1 luon la ten hang, bat dau tu cot 2 se la ma nha cung cap
        ' bien xac dinh cot de bat dau gan gia tri
        j = 1
        With Me
            For i = 0 To rs.Fields.Count - 1
                If Val(rs.Fields(i).Name) > 0 Then
                    .Controls("lbl_cr_" & j).Visible = True
                    .Controls("lbl_cr_" & j).Caption = GetColumnName(Val(rs.Fields(i).Name))
                    ' doi voi textbox thi dat ten vung so lieu luon
                    ' vi ten textbox la so nen phai co them ham chuyen gia tri sang chu
                    .Controls(CStr(j)).Visible = True
                    .Controls(CStr(j)).ControlSource = rs.Fields(i).Name
                    ' dinh dang so lieu
                    .Controls(CStr(j)).Format = "Standard"
                    .Controls(CStr(j)).DecimalPlaces = 0
                    j = j + 1
                End If
            Next
            ' Cac doi tuong khac thi giau di
            While j <= 9
                .Controls("lbl_cr_" & j).Visible = False
                ' doi voi textbox thi dat ten vung so lieu luon
                .Controls(CStr(j)).Visible = False
                j = j + 1
            Wend
        End With
        rs.Close
        DoCmd.Maximize
    End Sub