wkdxz 发表于 2022-10-11 16:18

【源码】【写给女友的软件①】批量匹配软件(类似Vlookup函数)

本帖最后由 wkdxz 于 2022-10-14 14:37 编辑

软件介绍:成品下载页


成品下载: https://www.52pojie.cn/thread-1697081-1-1.html

软件界面:
https://attach.52pojie.cn/forum/202210/10/141224mejn05qh20zgmrec.jpg




操作演示:(差不多,也就不更新了)
https://img1.imgtp.com/2022/10/09/Qwn4Xrr9.gif

使用Python字典匹配,按制表符tab分割源数据,如果分隔符不是tab,则默认按空格分割
使用 direction 切换匹配的方向是从左到右,还是右到左
def data_source_dic(shujuyuan, direction=True, fenge='\t'):
    if not (shujuyuan := shujuyuan.strip()):
      return
    data_source = shujuyuan.split('\n')
    if fenge not in data_source:
      fenge = ' '
    data_dic = {}
    with contextlib.suppress():
      for i in data_source:
            if i := i.strip():
                fen_list = i.split(fenge)
                if len(fen_list) > 1:#处理单列的情况
                  if direction:
                        k, *_, v = fen_list#左→右
                  else:
                        v, *_, k = fen_list#右←左
                else:
                  k = fen_list
                  v = ''
                if k not in data_dic:
                  data_dic = v.strip()
      return data_dic

从字典中取值,并返回匹配号的列表
def pipei(shujuyuan, daipipei):
    with contextlib.suppress():
      pipei_list = daipipei.split('\n')
      return

统计数据的行数,默认会去掉数据末的不可见字符
def count_items(strs, lclean=False):
    strs = strs.strip() if lclean else strs.rstrip()
    return len(strs.split('\n'))

GUI部分,使用Column来布局,感觉没有Frame好看
left_col = sg.Column(layout_left, element_justification='center', pad=(5))
mid_col = sg.Column(layout_mid, element_justification='center', pad=(5))
right_col = sg.Column(layout_right, element_justification='center', pad=(5))
bottom_left = sg.Column(layout_bottom_left, element_justification='left')
bottom_right = sg.Column(layout_bottom_right,
                         element_justification='center',
                         pad=(9))

逻辑判断部分,很渣,暂时没有找到更好的处理方法,幸好运行没问题
    if event == '粘数据源':
      window['数据源'].update(jtb)
      print(f'已粘贴{count_items(jtb)}条数据')
    if event == '清空数据源':
      window['数据源'].update('')
      window['log内容'].update('')
    if event == '粘待匹配':
      window['待匹配'].update(jtb)
      print(f'已粘贴{count_items(jtb)}条数据')
    if event == '清空待匹配':
      window['待匹配'].update('')
      window['log内容'].update('')
    if event == '执行匹配':
      print('执行匹配')
      window['结果'].update('')
      if not values['数据源'] or not values['待匹配']:
            print('数据源或待匹配数据为空,无法执行匹配')
      else:
            with contextlib.suppress():
                shujuyuan = data_source_dic(values['数据源'], values['左到右'])
                if pipei_list := pipei(shujuyuan, values['待匹配']):
                  window['结果'].update('\n'.join(pipei_list))

    if event == '复制结果':
      # print(event, values)
      res = values['结果']
      if res.strip():
            copy(res)
            print('✔ 已复制匹配结果')
      else:
            print('结果为空,没复制任何内容')
    if event == '清空结果':
      window['结果'].update('')
      window['log内容'].update('')


完整代码,喜欢的取走,欢迎意见建议,大家一起进步。
from pyperclip import copy, paste
import PySimpleGUI as sg
import contextlib


def data_source_dic(shujuyuan, direction=True, fenge='\t'):
    if not (shujuyuan := shujuyuan.strip()):
      return
    data_source = shujuyuan.split('\n')
    if fenge not in data_source:
      fenge = ' '
    data_dic = {}
    with contextlib.suppress():
      for i in data_source:
            if i:
                fen_list = i.split(fenge)
                if len(fen_list) > 1:#处理单列的情况
                  if direction:
                        k, *_, v = fen_list#左→右
                  else:
                        v, *_, k = fen_list#右←左
                else:
                  k = fen_list
                  v = ''
                if k not in data_dic:
                  data_dic = v.strip()
      return data_dic


def pipei(shujuyuan, daipipei):
    with contextlib.suppress():
      pipei_list = daipipei.split('\n')
      return


def count_items(strs, lclean=False):
    strs = strs.strip() if lclean else strs.rstrip()
    return len(strs.split('\n'))


sg.theme('GrayGrayGray')# 设置当前主题

#数据源
source_input = sg.Multiline('', key='数据源', size=(35, 20))
source_paste = sg.Button(' 粘数据源 ', key='粘数据源', pad=(8))
source_clean = sg.Button(' 清 空 ', key='清空数据源', pad=(8))

#待匹配
pipei_input = sg.Multiline('', key='待匹配', size=(30, 20))
pipei_paste = sg.Button(' 粘待匹配 ', key='粘待匹配', pad=(8))
pipei_clean = sg.Button(' 清 空 ', key='清空待匹配', pad=(8))

#结果
result_lookup = sg.Button(' 执行匹配 ',
                        key='执行匹配',
                        button_color='#ffa631',
                        pad=(8))
result_input = sg.Multiline('',
                            key='结果',
                            size=(30, 20),
                            background_color='#f0f0f0',
                            text_color='#ca6924')
result_copy = sg.Button(' 复 制 ', key='复制结果', pad=(8))
result_clean = sg.Button(' 清 空 ', key='清空结果', pad=(8))

#高级选项
zuoyou_true = sg.Radio('最左 ▶ 最右 (默认)', '模式', key="左到右", default=True, pad=(3))
zuoyou_false = sg.Radio('最左 ◀ 最右', '模式', key="右到左", pad=(3))

log_output = sg.Output(key='log内容',
                     size=(84, 3),
                     background_color='#f0f0f0',
                     text_color='#808080')

#放置组件
layout_left = [
    ,
    ,
]

layout_mid = [
    ,
    ,
]

layout_right = [
    ,
    ,
]

layout_bottom_left = [
    ,
    ,
]

layout_bottom_right = []

#将各组件转换为sg的列
left_col = sg.Column(layout_left, element_justification='center', pad=(5))
mid_col = sg.Column(layout_mid, element_justification='center', pad=(5))
right_col = sg.Column(layout_right, element_justification='center', pad=(5))
bottom_left = sg.Column(layout_bottom_left, element_justification='left')
bottom_right = sg.Column(layout_bottom_right,
                         element_justification='center',
                         pad=(9))

# 将列布局
layout = [
    ,
    ,
]

# 创建窗口
window = sg.Window(
    '匹配字符 - by wkdxz@52pojie.cn',
    layout,
    font=('微软雅黑', 10),
    element_justification='center',
    keep_on_top=True,
    finalize=True,
)

while True:
    event, values = window.read()
    if not event:
      break

    jtb = paste()

    if event == '粘数据源':
      window['数据源'].update(jtb)
      print(f'已粘贴{count_items(jtb)}条数据')
    if event == '清空数据源':
      window['数据源'].update('')
      window['log内容'].update('')
    if event == '粘待匹配':
      window['待匹配'].update(jtb)
      print(f'已粘贴{count_items(jtb)}条数据')
    if event == '清空待匹配':
      window['待匹配'].update('')
      window['log内容'].update('')
    if event == '执行匹配':
      print('执行匹配')
      window['结果'].update('')
      if not values['数据源'] or not values['待匹配']:
            print('数据源或待匹配数据为空,无法执行匹配')
      else:
            with contextlib.suppress():
                shujuyuan = data_source_dic(values['数据源'], values['左到右'])
                if pipei_list := pipei(shujuyuan, values['待匹配']):
                  window['结果'].update('\n'.join(pipei_list))

    if event == '复制结果':
      # print(event, values)
      res = values['结果']
      if res.strip():
            copy(res)
            print('✔ 已复制匹配结果')
      else:
            print('结果为空,没复制任何内容')
    if event == '清空结果':
      window['结果'].update('')
      window['log内容'].update('')

window.close()

wkdxz 发表于 2022-10-11 21:33

随遇而安8 发表于 2022-10-11 21:04
能不能指定提取多列,等待大佬2.0版本

可以只是需求量不大 所以没有做

wkdxz 发表于 2022-10-11 20:10

xzchina 发表于 2022-10-11 19:32
大佬问下是用什么工具录制的gif动画

不是大佬哈,Gif123论坛有下载的

Cacarot 发表于 2022-10-11 16:31

不错,学习一下

双翼 发表于 2022-10-11 16:45

这个对我有用,收藏下

kuwu 发表于 2022-10-11 17:15

大佬牛逼 学习一下

ww5270616 发表于 2022-10-11 17:20

这个也不错,感谢分享

ainihd 发表于 2022-10-11 18:04

成品在哪里下载

wkdxz 发表于 2022-10-11 18:22

ainihd 发表于 2022-10-11 18:04
成品在哪里下载

顶部有链接

ai28012801 发表于 2022-10-11 18:42

感谢分享

xzchina 发表于 2022-10-11 19:32

大佬问下是用什么工具录制的gif动画

Alex_107 发表于 2022-10-11 19:33

收藏,感谢分享
页: [1] 2 3 4
查看完整版本: 【源码】【写给女友的软件①】批量匹配软件(类似Vlookup函数)