sửa code python (3 người xem)

Người dùng đang xem chủ đề này

  • Tôi tuân thủ nội quy khi đăng bài
    Có

    Hoale85

    Thành viên chính thức
    Tham gia
    2/8/24
    Bài viết
    99
    Được thích
    7
    Em nhờ anh chị sửa giúp em code sau với ạ: đoạn chỗ kiểm tra checkbok:
    import cv2
    import numpy as np
    import os
    import glob
    import time
    import traceback
    import gc
    import ctypes

    # =========================================================
    # 0. CỐ ĐỊNH DPI TRƯỚC KHI NẠP PYAUTOGUI
    # =========================================================

    try:
    ctypes.windll.shcore.SetProcessDpiAwareness(2)
    except Exception:
    try:
    ctypes.windll.user32.SetProcessDPIAware()
    except Exception:
    pass

    import pyautogui
    import pyperclip
    import win32gui
    import win32con
    import win32com.client as win32

    import cv2
    import numpy as np


    # =========================================================
    # 1. CẤU HÌNH
    # =========================================================

    pyautogui.FAILSAFE = False
    pyautogui.PAUSE = 0.3

    URL_DANG_NHAP = (
    "https://amisapp.misa.vn/login/?href="
    "L0FQSVMvSW50ZWdyYXRpb25BUEkvYXBwL3JlZGlyZWN0L0FjY291bnRpbmc="
    )

    URL_BAO_CAO = (
    "https://actapp.misa.vn/app/RP/ReportList/"
    "RPDynamicViewer/GLBookDetailPaymentByAccountNumber"
    )

    DOWNLOAD_DIR = r"C:\Users\admin\Downloads"
    FILE_TONG = r"D:\Hoa lv\Kiem soat\128-341.xlsm"

    # KÍCH THƯỚC MÀN HÌNH CHUẨN
    CHUAN_RONG = 1920
    CHUAN_CAO = 1200

    MAN_HINH_KHOI_DAU = pyautogui.size()

    TY_LE_X = MAN_HINH_KHOI_DAU.width / CHUAN_RONG
    TY_LE_Y = MAN_HINH_KHOI_DAU.height / CHUAN_CAO

    print("=" * 65)
    print("THÔNG TIN MÀN HÌNH")
    print("Chiều rộng:", MAN_HINH_KHOI_DAU.width)
    print("Chiều cao:", MAN_HINH_KHOI_DAU.height)
    print("Tỷ lệ X:", TY_LE_X)
    print("Tỷ lệ Y:", TY_LE_Y)
    print("=" * 65)

    # Thời gian chờ
    CHO_MO_CHROME = 3
    CHO_TAI_TRANG = 8
    CHO_GOI_Y_128 = 2
    CHO_TAI_FILE = 120

    # Ảnh chụp checkbox
    THU_MUC_CODE = os.path.dirname(os.path.abspath(__file__))

    FILE_ANH_CHECKBOX = os.path.join(
    THU_MUC_CODE,
    "checkbox_screenshot.png"
    )

    FILE_ANH_SAU_CHECKBOX = os.path.join(
    THU_MUC_CODE,
    "checkbox_screenshot_after.png"
    )

    # Ngưỡng màu nhận diện viền xanh trong ảnh HSV
    # OpenCV Hue có giá trị từ 0 đến 179
    BLUE_H_MIN = 90
    BLUE_H_MAX = 135
    BLUE_S_MIN = 65
    BLUE_V_MIN = 65

    # Ngưỡng nhận diện dấu tích xanh bên trong checkbox
    GREEN_H_MIN = 35
    GREEN_H_MAX = 90
    GREEN_S_MIN = 55
    GREEN_V_MIN = 55

    # Kích thước dự kiến của khung viền xanh quanh checkbox
    KHUNG_MIN = 12
    KHUNG_MAX = 70


    # =========================================================
    # 2. KIỂM TRA VÀ CỐ ĐỊNH TỌA ĐỘ
    # =========================================================

    def kiem_tra_man_hinh():

    man_hinh_hien_tai = pyautogui.size()

    if (
    man_hinh_hien_tai.width != MAN_HINH_KHOI_DAU.width
    or man_hinh_hien_tai.height != MAN_HINH_KHOI_DAU.height
    ):
    raise Exception(
    "ĐỘ PHÂN GIẢI MÀN HÌNH ĐÃ THAY ĐỔI!\n"
    f"Lúc chạy: {MAN_HINH_KHOI_DAU.width}x{MAN_HINH_KHOI_DAU.height}\n"
    f"Hiện tại: {man_hinh_hien_tai.width}x{man_hinh_hien_tai.height}\n"
    "Vui lòng giữ nguyên độ phân giải màn hình."
    )


    def toa_do(x, y):

    kiem_tra_man_hinh()

    px = int(x * TY_LE_X)
    py = int(y * TY_LE_Y)

    return px, py


    def click_xy(x, y, so_lan=1):

    px, py = toa_do(x, y)

    pyautogui.moveTo(px, py, duration=0.2)

    pyautogui.click(
    px,
    py,
    clicks=so_lan,
    interval=0.15
    )


    def nhap_url(url):

    pyautogui.hotkey("ctrl", "l")
    time.sleep(0.3)

    pyperclip.copy(url)
    pyautogui.hotkey("ctrl", "v")

    pyautogui.press("enter")


    def dan_chu(chu):

    pyperclip.copy(str(chu))
    pyautogui.hotkey("ctrl", "v")


    # =========================================================
    # 3. DANH SÁCH CÔNG TY
    # =========================================================

    DS_CONG_TY = [
    {
    "ten": "KHOÁNG SẢN VŨ GIA YÊN BÁI",
    "tab": 4,
    "sheet": "128-VG_YENBAI"
    },
    {
    "ten": "CÔNG TY CỔ PHẦN CHĂN NUÔI CÔNG NGHỆ CAO VACA MAXI",
    "tab": 3,
    "sheet": "128-VACA"
    },
    {
    "ten": "CÔNG TY CỔ PHẦN CÔNG NGHỆ EMBERA",
    "tab": 3,
    "sheet": "128-EMBERA_TECH"
    },
    {
    "ten": "CÔNG TY CỔ PHẦN TẬP ĐOÀN EMBERA",
    "tab": 3,
    "sheet": "128-EMBERA_TD"
    },
    {
    "ten": "CÔNG TY CỔ PHẦN TẬP ĐOÀN MIT VIỆT NAM",
    "tab": 6,
    "sheet": "128-MIT"
    }
    ]


    # =========================================================

    # =========================================================

    def kiem_tra_checkbox():
    print("Đang chuyển đến ô Check Book...")

    # 1. Tab đúng 3 lần sau khi Enter 128
    for i in range(3):
    pyautogui.press('tab')
    time.sleep(0.3)

    # Chờ giao diện ổn định hoàn toàn sau khi di chuyển tiêu điểm Tab
    time.sleep(0.6)

    # 2. SỬ DỤNG TỌA ĐỘ TUYỆT ĐỐI BẠN ĐÃ ĐO THỰC TẾ (CỐ ĐỊNH)
    x_chuan = 614
    y_chuan = 364

    # Lấy mã màu RGB trực tiếp tại tọa độ này từ màn hình
    # Định dạng trả về là một bộ 3 số (R, G, B)
    rgb_color = pyautogui.pixel(x_chuan, y_chuan)
    r, g, b = rgb_color[0], rgb_color[1], rgb_color[2]

    print(f" Màu sắc thực tế đo được tại vị trí (614, 364) là: R={r}, G={g}, B={b}")

    # 3. KHÓA CỨNG LOGIC BẢO VỆ DỰA TRÊN MÀU SẮC THỰC TẾ
    # Dấu tích xanh lá cây của MISA có đặc điểm: Kênh Green (Xanh lá) lớn hẳn so với Red và Blue
    # Đồng thời kênh Red của màu xanh lá cây này rất thấp (thường < 100)
    if g > 130 and r < 120:
    # TRẠNG THÁI ĐÃ CÓ TÍCH XANH (NHƯ HÌNH BẠN GỬI) -> BỎ QUA 100%
    print("====== KẾT QUẢ: ĐÃ CÓ DẤU TÍCH V XANH -> BỎ QUA HOÀN TOÀN (KHÔNG ẤN PHÍM CÁCH) ======")
    # Nhánh này hoàn toàn trống rỗng, không chứa bất kỳ mã lệnh tương tác bàn phím nào cả

    else:
    # TRẠNG THÁI Ô TRỐNG TRẮNG (Hoặc không phải màu tích xanh) -> TIẾN HÀNH TÍCH CHỌN
    print("====== KẾT QUẢ: Ô ĐANG TRỐNG -> TIẾN HÀNH NHẤN SPACE ĐỂ TÍCH CHỌN ======")
    pyautogui.press('space')

    return True


    # =========================================================
    # 5. TÌM VÀ MỞ TAB CHROME
    # =========================================================

    def lay_danh_sach_cua_so_chrome():

    ket_qua = []

    def callback(hwnd, extra):

    try:
    if not win32gui.IsWindowVisible(hwnd):
    return True

    ten = win32gui.GetWindowText(hwnd)

    if "Chrome" in ten:
    ket_qua.append(hwnd)

    except Exception:
    pass

    return True

    win32gui.EnumWindows(callback, None)

    return ket_qua


    def lay_cua_so_chrome_hien_tai():

    hwnd = win32gui.GetForegroundWindow()

    if hwnd and win32gui.IsWindow(hwnd):

    ten = win32gui.GetWindowText(hwnd)

    if "Chrome" in ten:
    return hwnd

    windows = lay_danh_sach_cua_so_chrome()

    if not windows:
    raise Exception("Không tìm thấy cửa sổ Chrome đang mở.")

    return windows[0]


    def kich_hoat_chrome(hwnd):

    kiem_tra_man_hinh()

    if hwnd and win32gui.IsWindow(hwnd):

    win32gui.ShowWindow(
    hwnd,
    win32con.SW_MAXIMIZE
    )

    win32gui.SetForegroundWindow(hwnd)

    time.sleep(1)

    pyautogui.hotkey("ctrl", "0")

    time.sleep(1)

    kiem_tra_man_hinh()


    def mo_chrome_misa():

    print("Đang mở tab Chrome MISA mới...")

    hwnd = lay_cua_so_chrome_hien_tai()

    kich_hoat_chrome(hwnd)

    pyautogui.hotkey("ctrl", "t")

    time.sleep(1)

    nhap_url(URL_DANG_NHAP)

    time.sleep(CHO_MO_CHROME)

    print("Đã mở trang đăng nhập MISA.")

    return hwnd


    def dong_chrome_misa(hwnd):

    if not hwnd or not win32gui.IsWindow(hwnd):

    print("Không tìm thấy cửa sổ Chrome để đóng tab.")

    return

    print("Đang đóng 2 tab Chrome MISA mới...")

    kich_hoat_chrome(hwnd)

    pyautogui.hotkey("ctrl", "w")

    time.sleep(1)

    pyautogui.hotkey("ctrl", "w")

    time.sleep(2)

    print("Đã đóng 2 tab Chrome MISA.")


    # =========================================================
    # 6. CHỌN CÔNG TY
    # =========================================================

    def chon_cong_ty(ten_cong_ty):

    print("Đang chọn công ty:", ten_cong_ty)

    time.sleep(3)

    click_xy(1828, 131)

    time.sleep(3)

    click_xy(1804, 417)

    time.sleep(2)

    click_xy(1816, 411)

    time.sleep(2)

    click_xy(769, 475)

    pyautogui.hotkey("ctrl", "a")

    dan_chu(ten_cong_ty)

    time.sleep(5)

    click_xy(636, 532)

    time.sleep(1)

    click_xy(1258, 863)

    time.sleep(1)

    print("Đã chọn công ty.")


    # =========================================================
    # 7. VÀO KẾ TOÁN VÀ MỞ BÁO CÁO
    # =========================================================

    def vao_bao_cao():

    print("Đang vào phân hệ Kế toán...")

    time.sleep(2)

    click_xy(32, 137)

    time.sleep(1)

    dan_chu("kế toán")

    time.sleep(1)

    click_xy(145, 283)

    time.sleep(3)

    nhap_url(URL_BAO_CAO)

    time.sleep(CHO_TAI_TRANG)

    print("Đã mở báo cáo.")


    # =========================================================
    # 8. CHỌN THAM SỐ VÀ KIỂM TRA CHECKBOX
    # =========================================================

    def chon_tham_so(so_lan_tab):

    print("Đang chọn tham số báo cáo...")

    click_xy(1746, 204)

    time.sleep(2)

    for i in range(so_lan_tab):

    pyautogui.press("tab")

    time.sleep(0.3)

    pyautogui.hotkey("ctrl", "a")

    dan_chu("128")

    time.sleep(CHO_GOI_Y_128)

    pyautogui.press("enter")

    time.sleep(1)

    # Sau Enter 128, Tab đúng 3 lần đến checkbox
    kiem_tra_checkbox()

    print("Đã hoàn thành chọn tham số.")


    # =========================================================
    # 9. KIỂM TRA FILE DOWNLOAD
    # =========================================================

    def lay_trang_thai_download():

    trang_thai = {}

    for duoi in ("*.xlsx", "*.xls", "*.xlsm"):

    for file in glob.glob(
    os.path.join(DOWNLOAD_DIR, duoi)
    ):

    try:

    trang_thai[file] = (
    os.path.getmtime(file),
    os.path.getsize(file)
    )

    except Exception:
    pass

    return trang_thai


    def cho_file_tai_xong(trang_thai_cu, timeout=120):

    print("Đang chờ tải Excel...")

    bat_dau = time.time()

    file_on_dinh = None
    dem_on_dinh = 0
    kich_thuoc_cu = -1

    while time.time() - bat_dau < timeout:

    dang_tai = glob.glob(
    os.path.join(DOWNLOAD_DIR, "*.crdownload")
    )

    if dang_tai:

    time.sleep(1)

    continue

    danh_sach_moi = []

    for duoi in ("*.xlsx", "*.xls", "*.xlsm"):

    for file in glob.glob(
    os.path.join(DOWNLOAD_DIR, duoi)
    ):

    try:

    mtime = os.path.getmtime(file)

    size = os.path.getsize(file)

    thong_tin_cu = trang_thai_cu.get(file)

    if (
    thong_tin_cu is None
    or mtime > thong_tin_cu[0]
    or size != thong_tin_cu[1]
    ):

    danh_sach_moi.append(
    (mtime, file, size)
    )

    except Exception:
    pass

    if danh_sach_moi:

    danh_sach_moi.sort(reverse=True)

    _, file_hien_tai, kich_thuoc = danh_sach_moi[0]

    if (
    file_hien_tai == file_on_dinh
    and kich_thuoc == kich_thuoc_cu
    ):

    dem_on_dinh += 1

    else:

    file_on_dinh = file_hien_tai

    kich_thuoc_cu = kich_thuoc

    dem_on_dinh = 0

    if dem_on_dinh >= 3 and kich_thuoc > 0:

    print("Đã tải xong:", file_on_dinh)

    return file_on_dinh

    time.sleep(1)

    raise TimeoutError(
    "Quá thời gian chờ tải file Excel."
    )


    # =========================================================
    # 10. TẢI BÁO CÁO
    # =========================================================

    def tai_bao_cao():

    print("Đang thực hiện tải báo cáo...")

    trang_thai_cu = lay_trang_thai_download()

    click_xy(1768, 1108)

    time.sleep(3)

    click_xy(1703, 276)

    time.sleep(2)

    click_xy(1252, 868)

    time.sleep(2)

    click_xy(1130, 313)

    time.sleep(15)

    file_excel = cho_file_tai_xong(
    trang_thai_cu,
    CHO_TAI_FILE
    )

    return file_excel


    # =========================================================
    # 11. MỞ FILE EXCEL Ổ D, DÁN DỮ LIỆU, LƯU VÀ ĐÓNG
    # =========================================================

    def dan_du_lieu_vao_excel(file_nguon, ten_sheet):

    print("\nĐANG MỞ EXCEL ĐỂ DÁN DỮ LIỆU")

    print("File nguồn:", file_nguon)

    print("File đích:", FILE_TONG)

    print("Sheet đích:", ten_sheet)

    if not os.path.exists(file_nguon):

    raise FileNotFoundError(
    "Không tìm thấy file Excel vừa tải."
    )

    if not os.path.exists(FILE_TONG):

    raise FileNotFoundError(
    "Không tìm thấy file tổng hợp ở ổ D: " + FILE_TONG
    )

    excel = None

    wb_nguon = None

    wb_tong = None

    try:

    excel = win32.DispatchEx("Excel.Application")

    excel.Visible = True

    excel.DisplayAlerts = False

    excel.ScreenUpdating = True

    excel.EnableEvents = False

    print("Đang mở file Excel vừa tải...")

    wb_nguon = excel.Workbooks.Open(
    os.path.abspath(file_nguon),
    ReadOnly=True
    )

    ws_nguon = wb_nguon.Worksheets(1)

    time.sleep(2)

    print("Đang mở file tổng hợp ở ổ D...")

    wb_tong = excel.Workbooks.Open(
    os.path.abspath(FILE_TONG)
    )

    excel.Visible = True

    excel.WindowState = -4137

    wb_tong.Activate()

    time.sleep(2)

    print("Đang hiện các sheet ẩn...")

    for ws in wb_tong.Worksheets:

    if ws.Visible != -1:

    ws.Visible = -1

    try:

    ws_dich = wb_tong.Worksheets(ten_sheet)

    except Exception:

    raise Exception(
    "Không tìm thấy sheet đích: " + ten_sheet
    )

    ws_dich.Activate()

    time.sleep(1)

    print("Đang xóa dữ liệu cũ...")

    ws_dich.Cells.Clear()

    vung_nguon = ws_nguon.UsedRange

    print("Đang dán dữ liệu...")

    vung_nguon.Copy(
    Destination=ws_dich.Range("A1")
    )

    time.sleep(2)

    print("Đang lưu file tổng hợp...")

    wb_tong.Save()

    time.sleep(2)

    print("ĐÃ LƯU THÀNH CÔNG:", ten_sheet)

    finally:

    if wb_nguon is not None:

    try:
    wb_nguon.Close(SaveChanges=False)
    except Exception:
    pass

    if wb_tong is not None:

    try:
    wb_tong.Close(SaveChanges=True)
    except Exception:
    pass

    if excel is not None:

    try:
    excel.DisplayAlerts = False
    excel.Quit()
    except Exception:
    pass

    wb_nguon = None

    wb_tong = None

    excel = None

    gc.collect()

    time.sleep(1)

    print("ĐÃ ĐÓNG EXCEL HOÀN TOÀN.")


    # =========================================================
    # 12. XỬ LÝ TỪNG CÔNG TY
    # =========================================================

    def xu_ly_cong_ty(cong_ty):

    ten_cong_ty = cong_ty["ten"]

    so_lan_tab = cong_ty["tab"]

    ten_sheet = cong_ty["sheet"]

    hwnd_misa = None

    print("\n")

    print("=" * 65)

    print("BẮT ĐẦU:", ten_cong_ty)

    print("=" * 65)

    try:

    hwnd_misa = mo_chrome_misa()

    kich_hoat_chrome(hwnd_misa)

    chon_cong_ty(ten_cong_ty)

    vao_bao_cao()

    chon_tham_so(so_lan_tab)

    file_excel = tai_bao_cao()

    if not file_excel or not os.path.exists(file_excel):

    raise Exception(
    "Không tìm thấy file Excel sau khi tải."
    )

    dan_du_lieu_vao_excel(
    file_excel,
    ten_sheet
    )

    # Chỉ đóng Chrome sau khi Excel đã lưu và đóng xong
    kich_hoat_chrome(hwnd_misa)

    dong_chrome_misa(hwnd_misa)

    print("HOÀN THÀNH:", ten_cong_ty)

    return True

    except Exception as e:

    print("\nLỖI KHI XỬ LÝ:", ten_cong_ty)

    print("Chi tiết:", str(e))

    traceback.print_exc()

    print("Giữ nguyên tab Chrome để kiểm tra lỗi.")

    return False


    # =========================================================
    # 13. CHẠY TOÀN BỘ DANH SÁCH
    # =========================================================

    def main():

    print("\nBẮT ĐẦU CHẠY DANH SÁCH CÔNG TY")

    print("File tổng hợp:", FILE_TONG)

    print(
    "Màn hình đang sử dụng:",
    MAN_HINH_KHOI_DAU.width,
    "x",
    MAN_HINH_KHOI_DAU.height
    )

    if not os.path.exists(FILE_TONG):

    print("KHÔNG TÌM THẤY FILE TỔNG HỢP Ở Ổ D.")

    return

    if not os.path.isdir(DOWNLOAD_DIR):

    print("KHÔNG TÌM THẤY THƯ MỤC DOWNLOAD.")

    return

    kiem_tra_man_hinh()

    thanh_cong = 0

    that_bai = 0

    for i, cong_ty in enumerate(DS_CONG_TY, start=1):

    print("\n")

    print("#" * 65)

    print(
    "CÔNG TY",
    i,
    "/",
    len(DS_CONG_TY)
    )

    print("#" * 65)

    ket_qua = xu_ly_cong_ty(cong_ty)

    if ket_qua:

    thanh_cong += 1

    else:

    that_bai += 1

    time.sleep(2)

    print("\n")

    print("=" * 65)

    print("ĐÃ KẾT THÚC TOÀN BỘ CHƯƠNG TRÌNH")

    print("Thành công:", thanh_cong)

    print("Thất bại:", that_bai)

    print("=" * 65)


    # =========================================================
    # 14. KHỞI CHẠY
    # =========================================================

    if __name__ == "__main__":

    try:

    main()

    except Exception:

    print("\nLỖI CHƯƠNG TRÌNH:")

    traceback.print_exc()

    finally:

    input("\nNhấn ENTER để đóng chương trình...")
    đoạn check book ko dùng tọa độ mà kiểm tra tại vị trí tab 3 lần sau khi enter 128 để đảm bảo luôn chọn tất cả. nếu đã chọn tất cả thì bỏ qua1794134638462.png1794134591535.png
     

    Bài viết mới nhất

    Back
    Top Bottom