szllw 发表于 2020-4-12 18:59

Excel VBA 把对账单按照订单号单独保存为发票导入清单

本帖最后由 szllw 于 2020-4-13 12:17 编辑

客户发来的对账单,需要按照对账单开票,由于数量众多,手工分列文件效率慢又容易出错。所以写了一段代码,把对账单按照一个订单号码保存为一个文件,并且需要可以被发票清单导入工具导入。

1、客户发来的对账单(部分截图):




2、使用方法:
注意:
(1)不要修改【导出摸板 (TEST)】中的任何内容,任何修改,都会导致导出错误
(2)不要删除【当前开票对账单】中的任何行,只能选中后按del键删除内容,也不能移动内容,否则会导致主表格错误。
(3)打开文件必须要【启用宏】。

a)把客户发来的对账单按照标题行一一对应的复制内容到第二个表格【当前开票对账单】;b)转到【导出摸板 (TEST)】,点击定位空白行(这个步骤是因为客户发过来的名称可能有不符合发票系统名称的,需要把他添加到数据库A和数据库B中,添加内容后需要排序,因为用到的lookup函数是以二分查找法来查找,所以需要排序);
c)数据库A是把对账单的不符合发票系统名称转为统一名称,数据库B是用来查找单位的,因为客户发来的单位都是pc、ea、set、bag等,不符合中国人开票习惯;
d)在定位空白行移动到最后一行后,表示没有不符合发票标准的名称了(这个要按照你们发票系统的名称来修改);

e)打开宏,选择:导出清单___A一键导出发票清单★★★,即可在文件当前目录自动新建一个目录,目录下保存为以订单号为文件名的文件,这些文件都可以被发票清单导入工具导入(如有需要,请按照当地的发票系统修改相应代码)。


3、以下为导出的分列发票清单文件:



下面是其中一个发票清单的内容:

4、模板下载:

5、以下为代码:

Sub 导出清单___A一键导出发票清单★★★()
'**************************************************************
'*   功能:对账单一键导出所有发票清单                         *
'*   作者:LLW                                                *
'*   创建时间:2019-3-26                                    *
'*   版本:1.42020-03-23 功能修正:导出模板变更             *
'*   版本:1.32019-11-19 修复:订单号为文本时的运行错误   *
'*   版本:1.22019-04-18 增加:订单号清单追加序号列         *
'*   版本:1.12019-03-28 增加:包含导出发票订单号清单       *
'*   版本:1.02019-03-26 增加:一键导出所有发票清单         *
'**************************************************************
   
    '简单判断是否导出表,否则就不运行
    If (Range("K1").Value <> "订单号") Then
      MsgBox ("不能在这个表操作,请到【导出摸板 (TEST)】操作")
      End
    End If
   
    '***************************************************************
    '*****   当对账单订单号码以文本格式保存时,程序运行出错    *****
    '*****   把文本转为数字时解决错误。2019/11/19            *****
    '***************************************************************
    Sheets("当前开票对账单").Select
    With Intersect(ActiveSheet.UsedRange, )
      .NumberFormatLocal = "G/通用格式"
      .Value = .Value
    End With
    Sheets("导出摸板 (TEST)").Select
    '***************************************************************
   
    '获得当前表的名称
    Dim curWbName As String
    curWbName = ActiveSheet.Name

    '********** 清除筛选 **********
    '判断筛选状态
    If Sheets(curWbName).AutoFilterMode = True Then
   
      '不论当前是否是筛选状态,保证A1所在区域成为筛选状态
      Range("A1").AutoFilter Field:=1
      
      '解除筛选状态。(注意因为上一句代码,已经保证成为筛选状态了)
      Range("A1").AutoFilter
      
      'ActiveSheet.ShowAllData
      Range("A1").Select
      
    End If
    '*****************************
   
    Dim arr
    arr = Range("A1:K" & .End(3).Row)
   
    '定义变量
    Dim i As Long, wName As String, wPath As String
   
    '建立的文件夹名称
    wName = "发票清单 " & Format(Date)
   
    '定义变量
    Dim dc As Object, wb As Workbook, n As Long
    Set dc = CreateObject("Scripting.dictionary")
   
    '工作路径
    wPath = ThisWorkbook.Path & "\" & wName
   
    '建立目录
    If Dir(wPath, vbDirectory) = "" Then
      MkDir wPath
    End If
   
    '序号赋值到新表格
    Dim No
    No = 1
   
    Dim curOrder, preOrder
    curOrder = arr(2, 11)                           'arr(2, 11) 第2行,第11列
   
    '************ 把发票总清单中的内容以订单号为文件名单独导出保存 ************
    '循环开始
    For i = 2 To UBound(arr)
   
      If arr(i, 11) = 0 Then                      '如果订单号是0,则退出循环
            No = 1
            Workbooks(curOrder & ".xls").Close True
            Exit For
      End If
      
      If Not arr(i, 11) = arr(i - 1, 11) Then   '如果当前订单号和上一条订单号不相同,则
                        
            '把当前订单号赋值给上一订单号,后面用过来关闭文件
            If Not arr(i - 1, 11) = "订单号" Or arr(i - 1, 11) = 0 Then
                preOrder = curOrder
            End If
            
            curOrder = arr(i, 11)
            
            '关闭并保存前订单文件
            If Not preOrder = "" Then
            
                Workbooks(preOrder & ".xls").Activate   '切换到要关闭的工作表
               
                '*******文字居中********
                Columns("B:I").Select
                With Selection
                  .HorizontalAlignment = xlCenter
                  .VerticalAlignment = xlCenter
                End With
               
                Range("A2").Select
                With Selection
                  .HorizontalAlignment = xlCenter
                  .VerticalAlignment = xlCenter
                End With
               
                Columns("A:A").ColumnWidth = 38.38
                Rows(1).AutoFit
                Columns("B:I").EntireColumn.AutoFit
                '*******文字居中********
            
                Workbooks(preOrder & ".xls").Close True   '003
            End If
      
            '序号在新文件中初始化为1
            No = 1
            
            '新建表格
            Set wb = Workbooks.Add

            '设置表的名称
            wb.Sheets(1).Name = arr(i, 11)
            
            '********** 以03格式保存xls文件 **********
            wb.SaveAs Filename:=wPath & "\" & arr(i, 11) & ".xls", FileFormat:=xlExcel8, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False

            '********** 以07或以上格式保存xlsx文件 **********
            'wb.SaveAs Filename:=wPath & "\" & arr(i, 11) & ".xlsx", FileFormat:=xlOpenXMLWorkbook, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False
            
            '********** 保存文件,默认xlsx格式 **********
            'wb.SaveAs wPath & "\" & arr(i, 11) & ".xlsx"   '001
            
      End If
      
      '************ 填写表头(标题行) ************
      If Not dc.exists(arr(i, 11)) And No = 1 Then
            Columns("A:A").ColumnWidth = 40
            Cells(1, 1).Value = "注意:" & vbCrLf & "   1、模板中最多可录入2000行记录,超出的部分将在导入时被舍弃。" & vbCrLf & "    2、红颜色标示的字段为必填列 "               '提示:注意"
            Cells(1, 4).Value = "不含税金额"
            Cells(1, 5).Formula = "=SUM(G3:G2002)"
            Cells(1, 6).Value = "行数"
            Cells(1, 7).Formula = "=COUNTA(A3:A2002)"
            Cells(1, 8).Value = "总金额"
            Cells(1, 9).Formula = "=SUM(I3:I2002)"

            wb.Sheets(1). = arr(1, 2)   '商品名称
            wb.Sheets(1). = arr(1, 3)   '规格
            wb.Sheets(1). = arr(1, 4)   '单位
            wb.Sheets(1). = arr(1, 5)   '数量
            wb.Sheets(1). = arr(1, 6)   '不含税单价
            wb.Sheets(1). = arr(1, 7)   '税率
            wb.Sheets(1). = arr(1, 8)   '不含税金额
            wb.Sheets(1). = arr(1, 9)   '税额
            wb.Sheets(1). = arr(1, 10)   '价税合计
            'wb.Sheets(1). = arr(1, 11)    '新表不需要订单号

            '自适应所有列宽
            'Columns("A:I").Select            '选择列
            'Rows(1).RowHeight = 40
            'Columns("A:A").ColumnWidth = 40
            'Rows(1).AutoFit
            'Columns("B:I").EntireColumn.AutoFit
            'Rows(1).EntireColumn.AutoFit

            
      End If
      
      '************ 数据填充 ************
      
      With Workbooks(arr(i, 11) & ".xls").Sheets(1)   '002
            n = ..End(3).Row + 1
            .Cells(n, 1) = arr(i, 2)                  '商品名称
            If No = 1 Then
                .Cells(n, 2) = "项目" & arr(i, 3)       '规格(第一个项目加上文本)
            Else
                .Cells(n, 2) = arr(i, 3)
            End If
            .Cells(n, 3) = arr(i, 4)                  '单位
            .Cells(n, 4) = arr(i, 5)                  '数量
            .Cells(n, 5) = arr(i, 6)                  '不含税单价
            .Cells(n, 6) = 0.13                         '税率       (固定值:0.13)
            .Cells(n, 7).Formula = "=ROUND(D" & No + 2 & "*E" & No + 2 & ",2)"                      '不含税金额 (公式)
            .Cells(n, 8).Formula = "=ROUND(D" & No + 2 & "*E" & No + 2 & "*F" & No + 2 & ",2)"      '税额       (公式)
            .Cells(n, 9).Formula = "=G" & No + 2 & "+H" & No + 2                                    '价税合计   (公式)
      End With
      No = No + 1

    Next
    '循环结束

    '*********************** 生成数据透视表 **********************
    Dim nFpList
    '建立的文件夹名称
    nFpList = "订单号清单_" & Format(Date)
    '在创建透视表时,表名不能包含"-"符号,替换成下划线
    nFpList = Replace(nFpList, "-", "_")
   
    '定义都是表的变量
    Dim nPivotTables
    '设定透视表类型:4,6
    nPivotTables = "数据透视表1"
   
    '全部选择
    Cells.Select
    '复制选中的范围
    Selection.Copy
    '新建文件
    Workbooks.Add
    '给新建文件名设置表名
    Sheets("Sheet1").Name = "数据清单"
   
    '文本方式粘贴内容
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    '自动适应列宽
    Columns("A:R").EntireColumn.AutoFit
   
    Columns("L:R").Select               '删除无用信息:不含税金额135579.86   行数    2000    总金额153205.45
    Selection.Delete Shift:=xlToLeft

    '复制区域边缘不闪动
    Application.CutCopyMode = False
    '新建表
    Sheets.Add
    '给透视表设置表名
    Sheets("Sheet2").Name = nFpList
   
    '建立透视表 Version DefaultVersion xlPivotTableVersion10
    ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
      "数据清单!R1C1:R2003C11", Version:=6).CreatePivotTable TableDestination _
      :=nFpList & "!R3C1", TableName:=nPivotTables, DefaultVersion:=6

    '透视表操作
    Sheets(nFpList).Select
    Cells(3, 1).Select
    With ActiveSheet.PivotTables(nPivotTables).PivotFields("订单号")
      .Orientation = xlRowField
      .Position = 1
    End With
   
    '添加数量和金额字段
    ActiveSheet.PivotTables(nPivotTables).AddDataField ActiveSheet.PivotTables(nPivotTables).PivotFields("数量"), "计数项:数量", xlCount
    ActiveSheet.PivotTables(nPivotTables).AddDataField ActiveSheet.PivotTables(nPivotTables).PivotFields("不含税金额"), "求和项:不含税金额", xlSum
   
    '筛选取消订单号为0、为空的选项
    With ActiveSheet.PivotTables(nPivotTables).PivotFields("订单号")
      .PivotItems("0").Visible = False
      .PivotItems("(blank)").Visible = False
    End With

    '选取一个表的所有范围
    Cells.Select
    '复制
    Selection.Copy
    '文本粘贴
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
    '删除“数据清单”表
    Application.DisplayAlerts = False
    Sheets("数据清单").Delete
    Application.DisplayAlerts = True
    '选择第1,2行
   Rows("1:2").Select
    '删除第一第二无用的行
    Selection.Delete Shift:=xlUp

    '修改字段名称
    Cells(1, 1).Value = "订单号"
    Cells(1, 2).Value = "项数"
    Cells(1, 3).Value = "金额"
    Cells(1, 4).Value = "发票"
    Cells(1, 5).Value = "清单"

    '添加序号列
    Columns("A:A").Select
    Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
    Range("A1").Select
    ActiveCell.FormulaR1C1 = "序号"

    '************以计数项排序*************
    Range("A1:F100").Select
    ActiveWorkbook.Worksheets(nFpList).Sort.SortFields.Clear
    ActiveWorkbook.Worksheets(nFpList).Sort.SortFields.Add2 Key:=Range("C2:C100"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    'ActiveWorkbook.Worksheets(nFpList).Sort.SortFields.Add2 Key:=Range("B2:C" & i), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets(nFpList).Sort
      .SetRange Range("A1:F100")
      .Header = xlYes
      .MatchCase = False
      .Orientation = xlTopToBottom
      .SortMethod = xlPinYin
      .Apply
    End With
    '************************************
   
    Range("A2").Select
    '遇到总计就退出,遇到有内容就编号
    For i = 1 To 100
      If Cells(i + 1, "B") = "总计" Then
            Exit For
      ElseIf Not Cells(i + 1, "B") = "" Then
            Cells(i + 1, "A").Value = i
      End If
    Next i
   
    '************************↓设置细表格↓************************
    Range("A1:F" & i + 1 & "").Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
      .LineStyle = xlContinuous
      .ColorIndex = xlAutomatic
      .TintAndShade = 0
      .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeTop)
      .LineStyle = xlContinuous
      .ColorIndex = xlAutomatic
      .TintAndShade = 0
      .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeBottom)
      .LineStyle = xlContinuous
      .ColorIndex = xlAutomatic
      .TintAndShade = 0
      .Weight = xlThin
    End With
    With Selection.Borders(xlEdgeRight)
      .LineStyle = xlContinuous
      .ColorIndex = xlAutomatic
      .TintAndShade = 0
      .Weight = xlThin
    End With
    With Selection.Borders(xlInsideVertical)
      .LineStyle = xlContinuous
      .ColorIndex = xlAutomatic
      .TintAndShade = 0
      .Weight = xlHairline
    End With
    With Selection.Borders(xlInsideHorizontal)
      .LineStyle = xlContinuous
      .ColorIndex = xlAutomatic
      .TintAndShade = 0
      .Weight = xlHairline
    End With
    '************************↑设置细表格↑************************
   
    '设置字体和大小
    Columns("A:F").Select
    With Selection.Font
      .Name = "等线"
      .Size = 20
      .Strikethrough = False
      .Superscript = False
      .Subscript = False
      .OutlineFont = False
      .Shadow = False
      .Underline = xlUnderlineStyleNone
      .ThemeColor = xlThemeColorLight1
      .TintAndShade = 0
      .ThemeFont = xlThemeFontMinor
    End With
   
    '设置行高
    Rows("1:100").Select
    Selection.RowHeight = 35
      
    '设置列宽
    Columns("A").ColumnWidth = 8.2      '序号
    Columns("B").ColumnWidth = 20       '订单
    Columns("C").ColumnWidth = 10       '项数
    'Columns("D").ColumnWidth = 11      '金额
    Columns("D").EntireColumn.AutoFit   '金额项金额变化,需要自动适配宽度
    Columns("E").ColumnWidth = 15       '发票
    Columns("F").ColumnWidth = 15       '清单
   
    '整个表格文字左右居中
    Columns("A:F").Select
    With Selection
      .HorizontalAlignment = xlCenter   '左右居中
      .VerticalAlignment = xlCenter       '上下居中
    End With
   
    '金额项数字部分右对齐,标题居中
    Columns("D").Select
    With Selection
      .HorizontalAlignment = xlRight
      .VerticalAlignment = xlCenter
    End With
    Range("D1").Select
    With Selection
      .HorizontalAlignment = xlCenter
      .VerticalAlignment = xlCenter
    End With
    '******************************

    '设置页边距

With Sheets(nFpList).PageSetup
      .LeftMargin = Application.InchesToPoints(0.196850393700787)
      .RightMargin = Application.InchesToPoints(0.196850393700787)
      .TopMargin = Application.InchesToPoints(0.590551181102362)
      .BottomMargin = Application.InchesToPoints(0.196850393700787)
      .HeaderMargin = Application.InchesToPoints(0.196850393700787)
      .FooterMargin = Application.InchesToPoints(0.236220472440945)
      .CenterHorizontally = True'水平居中
    End With
    Range("A1").Select
   
    '保存文件
    'ChDir "C:\Users\" & Environ("username") & "\Desktop\"
    ActiveWorkbook.SaveAs Filename:=wPath & "\订单号清单 " & Format(Date) & ".xls", FileFormat:=xlExcel8, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False, CreateBackup:=False

End Sub

szllw 发表于 2020-4-12 19:37

wubwu33 发表于 2020-4-12 19:31
楼主,代码是用什么软件编辑的?
Office中的Word、Excel自带VB编辑器



szllw 发表于 2021-10-20 12:54

guorenming111 发表于 2021-10-20 11:24
如果发票超额,要拆分每张发票不超过10W的拆分,有工具的吗?

另写代码,每行金额相加,在下一行超过10W时,则截止到当前行导出。

制冷设备 发表于 2020-4-12 19:13

谢谢楼主分享!

你收到一条消息 发表于 2020-4-12 19:18

好人一生平安

wubwu33 发表于 2020-4-12 19:31

楼主,代码是用什么软件编辑的?

zzl888 发表于 2020-4-12 19:53

实用性很高,感谢楼主分享

goodmg 发表于 2020-4-12 20:18

谢谢分享!

liclub 发表于 2020-4-13 08:12

感谢分享

cj13888 发表于 2020-4-14 09:58

学习借鉴一下,谢谢分享

evilfarmer 发表于 2020-6-3 00:54

这是个好东西
页: [1] 2 3
查看完整版本: Excel VBA 把对账单按照订单号单独保存为发票导入清单