目录
  • 一、前言
  • 二、代码实现及讲解
    • 1.模块的导入
    • 2.获取“数据原表”中数据
    • 3.获取生产记录更新表中的日期和材料
    • 4.对生产数据更新表中数据的修改
    • 5.最后,调用函数并保存数据
  • 三、效果展示
    • 四、结尾

      一、前言

      大家好,今天我来介绍我接一个Python单子。我完成这个单子前后不到2小时。首先我接到这个单子的想法是处理Excel表,在两个表之间建立联系,并通过项目需求,修改excel表中的数据。我是运用面向过程写的,将每一步都放在了不同的函数中,下面让我来介绍一下我是怎么通过自己的思路一步一步完成的。

      先上客户的需求:

      利用Python改正excel表格数据

      二、代码实现及讲解

      1.模块的导入

      主要用到的模块为openpyxl、random

      import openpyxl
      import random
      from  openpyxl.utils.cell import get_column_letter,column_index_from_string

      除了运用到openpyxl和random还用到了openpyxl中的utils包下cell模块的两个方法,第一个方法get_column_letter的作用是将整型转换为对应excel中列属性的字符串,例如:12转换为L,50转换为AX

      第二个方法是将字符串转换为整型,其本质类似于10进制和27进制之间的转换,当然你也可以自己写,下面附上自己写的行(整型)转换为列(字符串)的代码。

      def num_to_string(n):
          column = n - 1
          real_colum = ''
          while column >= 26:
              value = column // 26
              column = column % 26
              real_colum += chr(value + 64)
          real_colum += chr(column + 65)
          return real_colum

      2.获取“数据原表”中数据

      #创建一个全局变量MATERIAL_MESSAGE
      MATERIAL_MESSAGE = []
      #获取小宛中数据
      def get_construct_message():
          #读取数据原表.xlsx表
          wb = openpyxl.load_workbook('数据原表.xlsx')
          #获取获取当前活动工作表,默认为第一个表
          ws = wb.active
          #获取在生产记录更新.xlsx中的可以用到的数据存入MATERIAL_MESSAGE中
          for row in range(1,ws.max_row + 1):
              if ws[f'A{row}'].value == '日期':
                  for i in range(ord('B'),ord('I')):
                      material = []
                      #将日期转换为与生产记录更新中相对应写法的形式
                      date = ws[f'B{row}'].value.translate(str.maketrans('年月','--'))
                      date = date.replace('号','')
                      material.append(date)
                      i = chr(i)
                      material.append(ws[f'{i}{row + 1}'].value)
                      material.append(ws[f'{i}{row + 3}'].value)
                      MATERIAL_MESSAGE.append(material)
          print(MATERIAL_MESSAGE)

      3.获取生产记录更新表中的日期和材料

      # 将客户要求的对应数据存入字典中
      TABLES = {"水泥":"水泥1","粉煤灰":"煤灰","河沙":"沙1","粗骨料1":"石1","粗骨料2":"石2","减水剂":"外加剂","水":"水"}
      #存入生产记录更新表的日期和其所在的行数
      DATE = []
      #存入生产记录更新表的材料和其所在的列数
      MATERIAL = []
      wb = openpyxl.load_workbook('生产记录更新.xlsx')
      ws = wb.active
      #获取日期
      def get_date():
          for row in range(3,ws.max_row + 1):
              #将日期进行分割合并转换成与MATERIAL_MESSAGE中对应日期的格式
              date = str(ws[f'B{row}'].value).split()[0]
              date_list = date.split('-')
              if '0' in date_list[1]:
                  date_list[1] = date_list[1].replace('0','')
              if '0' in date_list[2]:
                  date_list[2] = date_list[2].replace('0','')
              date = '-'.join(date_list)
              DATE.append([date,row])
          pprint.pprint(DATE)
      
      #获取材料
      def get_material():
          n = 0
          for column in ws[1]:
              n += 1
              #判断该单元格的内容是否在TABLES中
              if column.value in TABLES.values():
              #运用行列转换的方法进行转换
                  MATERIAL.append([column.value,get_column_letter(n - 1)])
          pprint.pprint(MATERIAL)

      DATE表部分数据:

      利用Python改正excel表格数据

      MATERIAL表数据:

      利用Python改正excel表格数据

      4.对生产数据更新表中数据的修改

      #两个参数分别为材料的类型和所在的列数
      def update_default(matrial,letter):
          for row in range(3,ws.max_row + 1):
              #判断单元格是否为空
              if ws[f'{letter}{row}'].value != None:
                  for i in range(len(MATERIAL_MESSAGE)):
                      #需求条件,要将连个表中的日期和材料类型进行一一对应
                      if DATE[row-3][0] == MATERIAL_MESSAGE[i][0] and matrial == TABLES[MATERIAL_MESSAGE[i][1]]:
                          #修改形参letter对应列的每个符号要求的单元格对应的设定值
                          ws[f'{letter}{DATE[row - 3][1]}'].value = MATERIAL_MESSAGE[i][2]
                          #分别获取该列列号的下两列对应的列号
                          letter_random = get_column_letter(column_index_from_string(letter) + 2)
                          letter_real = get_column_letter(column_index_from_string(letter) + 1)
                          #判断该列是否在这三列中,若在其中则得到-2到2之间的随机数,否则-1到1之间的随机数,并更新误差值
                          if letter in ('AV','BB','BE'):
                              ws[f'{letter_random}{DATE[row - 3][1]}'].value = round(random.uniform(-2, 2), 1)
                          else:
                              ws[f'{letter_random}{DATE[row - 3][1]}'].value = round(random.uniform(-1, 1), 1)
                          #运用设定值和误差值更新中间的实际值
                          ws[f'{letter_real}{DATE[row - 3][1]}'].value = round(ws[f'{letter}{DATE[row - 3][1]}'].value * (1 + ws[f'{letter_random}{DATE[row - 3][1]}'].value * 0.01),2)

      5.最后,调用函数并保存数据

      def main():
      
          get_construct_message()
          get_date()
          get_material()
          for i in MATERIAL:
              update_default(i[0],i[1])
          wb.save('生产记录更新.xlsx')
      
      if __name__ == "__main__":
          main()

      三、效果展示

      修改前部分数据:

      利用Python改正excel表格数据

      修改后部分数据:

      利用Python改正excel表格数据

      四、结尾

      总的来说,难度不在于怎么修改数据,而是在于怎么把两个表相互关联,通过这次接单让我对excel表能够更加熟练地进行操作,接单既能提升自己的能力,又能赚点外快,何乐而不为呢?

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。