excel审计底稿生成工具,excel审计底稿怎么编辑文字

首页 > 实用技巧 > 作者:YD1662023-11-23 15:50:00

​​​本文于2023年8月15日首发于本人同名公众号:Excel活学活用,更多文章敬请关注!

快速浏览

往期合集:【2023年3月】【2023年4月】【2023年5月】【2023年6月】【2023年7月】

实用案例

|收费管理系统|中医诊所收费系统|

|日期控件|简单的收发存|

|电子发票管理助手|Excel表格拆分神器|

|Excel多种类型文件合并|电子发票登记系统(Access版)|

收费使用项目

|财务管理系统|

内容提要

大家好,我是冷水泡茶,前两天在论坛上看到一个求助贴:

excel审计底稿生成工具,excel审计底稿怎么编辑文字(1)

他的明细表“序时账”是这样的,有几千条数据:

excel审计底稿生成工具,excel审计底稿怎么编辑文字(2)

还有一张“会计凭证抽查”表,(已被我改为“凭证抽查(模板)”):

excel审计底稿生成工具,excel审计底稿怎么编辑文字(3)

他的需求是:从“序时账”中抽出“现金”科目借方金额排名前3的凭证,填到这张抽查表中,作为审计底稿。

有很多人给出了方法,有用数组、字典的,也有用SQL的,都能达到目的。我看这么多人都做了,也看了几个答案,也就没有掺和。那你不禁要问:你到底在说什么?

请先别急,前面是引子,下面是我今天的重点:

楼主开始只要做一个“现金”科目,后来又提了不少要求,包括改变科目等。我突然想起我们做过不少批量生成工作表、循环打印工作表等案例,像他这样做审计的话,是不是会有这种需求:把所有科目,或者说选择几个科目做成会计凭证抽查底稿呢?

我觉得这种需求应该是很多人都会有的,于是就着手做了起来,走不不少弯路,这里就不多说了,我们看结果:

基本思路

1、把所有科目列出来,供选择,由于科目较多,我们选择用ListBox。

2、设置查询条件:

(1)排序方式:前几名、随机;

(2)凭证数量:预置1~10,供选择,也可以手输;

(4)金额方向:借、贷,根据明细账中相应字段设置为“借方金额”、“贷方金额”。

3、可以直接打印,也可以生成表格。

4、设置一个窗体,把这些控件放上去。

excel审计底稿生成工具,excel审计底稿怎么编辑文字(4)

程序代码

1、用户窗体UserForm1:

Dim arrData() Dim arrTem() Dim arrAccName() Private Sub CmbDirection_Change() accDirection = Me.CmbDirection.Text End Sub Private Sub CmbQuantity_Change() RdQuantity = Me.CmbQuantity End Sub Private Sub CmbSortType_Change() SortType = Me.CmbSortType End Sub Private Sub CmdCreateSheets_Click() '循环ListBox For i = 0 To Me.LstAccName.ListCount - 1 If Me.LstAccName.Selected(i) Then accName = Me.LstAccName.List(i) Call SelectData(accName) Call CopyWorksheet(accName) End If Next MsgBox "抽查表已生成!" Unload Me End Sub Private Sub CmdExit_Click() Unload Me End Sub Private Sub CmdPrint_Click() If Application.Dialogs(xlDialogPrinterSetup).Show = False Then Exit Sub End If '循环ListBox For i = 0 To Me.LstAccName.ListCount - 1 If Me.LstAccName.Selected(i) Then accName = Me.LstAccName.List(i) Call SelectData(accName) Call PrintSheet End If Next MsgBox "抽查表打印完成!" Unload Me End Sub Private Sub CmdSelectAll_Click() '选择 lstaccname 中的所有项目 If Me.CmdSelectAll.Caption = "全选" Then For i = 0 To LstAccName.ListCount - 1 LstAccName.Selected(i) = True Next Me.CmdSelectAll.Caption = "全消" Else For i = 0 To LstAccName.ListCount - 1 LstAccName.Selected(i) = False Next Me.CmdSelectAll.Caption = "全选" End If End Sub Private Sub UserForm_Initialize() Set cnn = CreateObject("Adodb.connection") Set rs = CreateObject("Adodb.Recordset") Set wb = ThisWorkbook Set ws = ThisWorkbook.Sheets("凭证抽查(模板)") Set rng = ws.Range("A1:L13") '排序类型:取前几大金额或者随机取几个 With Me.CmbSortType .Clear .AddItem "前几" .AddItem "随机" .Text = "前几" End With SortType = Me.CmbSortType '抽取凭证数量,预置1~10,可直接修改 For i = 1 To 10 Me.CmbQuantity.AddItem i Next Me.CmbQuantity = 5 RdQuantity = Me.CmbQuantity '金额方向,取标题字段中包含“借”、“贷”字符的字段。 Set ws = ThisWorkbook.Sheets("序时账") With Me.CmbDirection .Clear With ws For i = 1 To ws.UsedRange.Columns.Count If InStr(.Cells(1, i), "借") Or InStr(.Cells(1, i), "贷") Then Me.CmbDirection.AddItem .Cells(1, i) End If Next End With .Text = .List(0) accDirection = .Text End With '数据库连接相关,取得“科目名称”(一级科目),原始数据如果不是一级科目的要转换成一级科目。 DbFile = ThisWorkbook.FullName StrCnn = "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties=Excel 12.0;Data Source=" & DbFile cnn.Open StrCnn SQL = "select distinct left(科目代码,4) as 科目代码,科目名称 from (select * from [序时账$] where len(科目代码) >0 order by 科目代码)" Set rs = cnn.Execute(SQL) arrAccName = rs.getrows '科目名称装入ListBox For i = 0 To UBound(arrAccName, 2) Me.LstAccName.AddItem arrAccName(1, i) Next End Sub

‍代码解析:

(1)窗体初始化,设置几个控件的初始值,把会计科目装入ListBox。

(2)几个条件控件,当他们发生改变时,更新相应的变量值。

(3)全选按钮,点一下选择所有科目,再点一下取消选择。

(4)直接打印,循环ListBox,根据选择的科目,调用SelectData过程,PrintSheet过程。

(5)生成表格,循环ListBox,根据选择的科目,调用SelectData过程,CopyWorksheet过程。

2、myModule模块:

Public DbFile As String Public StrCnn As String Public cnn As Object Public rs As Object Public SQL As String Public AccCode As String, accName As String Public ws As Worksheet Public SortType As String Public RdQuantity As Integer Public accDirection As Variant Public wb As Workbook Public rng As Range Sub SelectData(accName As String) Dim arrData(), tbTitle() Dim arrTem(), arrSelected() Dim arr1() Dim iRow As Integer Dim iCol As Integer Dim DateAndNo As String Dim lastRow As Long Set ws = ThisWorkbook.Sheets("凭证抽查(模板)") If SortType = "前几" Then SQL = "select top " & RdQuantity & " *" _ & " from [序时账$] where 科目名称='" & accName _ & "' and len(凭证字号)>0 ORDER BY " & accDirection & " DESC" Set rs = cnn.Execute(SQL) arrTem = rs.getrows iRow = UBound(arrTem, 2) iCol = UBound(arrTem, 1) ReDim arr1(0 To iRow, 0 To iCol) For i = 0 To UBound(arrTem, 2) For j = 0 To UBound(arrTem, 1) arr1(i, j) = arrTem(j, i) Next Next For i = 0 To Application.WorksheetFunction.Min(RdQuantity - 1, UBound(arr1, 1)) DateAndNo = DateAndNo & arr1(i, 0) & arr1(i, 1) & "','" Next DateAndNo = "'" & Left(DateAndNo, Len(DateAndNo) - 2) SQL = "select a.日期,a.凭证字号,a.摘要,a.科目名称,a.二级科目,a.借方金额,a.贷方金额 from [序时账$] a where 日期 & 凭证字号 in (" & DateAndNo & ")" Else SQL = "select distinct 日期,凭证字号 from [序时账$] where 科目名称='" & accName _ & "' and len(" & accDirection & ")>0 " Set rs = cnn.Execute(SQL) arrTem = rs.getrows iRow = UBound(arrTem, 2) iCol = UBound(arrTem, 1) ReDim arr1(0 To iRow, 0 To iCol) For i = 0 To UBound(arrTem, 2) For j = 0 To UBound(arrTem, 1) arr1(i, j) = arrTem(j, i) Next Next For i = 1 To 5 arr1 = ShuffleArray(arr1) Next For i = 0 To Application.WorksheetFunction.Min(RdQuantity - 1, UBound(arr1, 1)) strDate = strDate & arr1(i, 0) & "#,#" strNo = strNo & arr1(i, 1) & "','" DateAndNo = DateAndNo & arr1(i, 0) & arr1(i, 1) & "','" Next strDate = "#" & Left(strDate, Len(strDate) - 2) strNo = "'" & Left(strNo, Len(strNo) - 2) DateAndNo = "'" & Left(DateAndNo, Len(DateAndNo) - 2) SQL = "select a.日期,a.凭证字号,a.摘要,a.科目名称,a.二级科目,a.借方金额,a.贷方金额 from [序时账$] a where 日期 & 凭证字号 in (" & DateAndNo & ")" End If Set rs = cnn.Execute(SQL) arrData = rs.getrows iRow = UBound(arrData, 2) iCol = UBound(arrData, 1) ReDim arr1(0 To iRow, 0 To iCol) For i = 0 To UBound(arrData, 2) For j = 0 To UBound(arrData, 1) arr1(i, j) = arrData(j, i) Next Next ws.Activate With ws .Range("C4") = accName lastRow = ws.UsedRange.Rows.Count If lastRow > 13 Then .Range("a11:L" & lastRow - 3).Delete Shift:=xlUp .Range("A10:G10").ClearContents .Range("F11:G11").ClearContents [a11].Resize(iRow).EntireRow.Insert End With With Range("A10").Resize(iRow 1, 12) .Columns(6).Resize(, 2).NumberFormatLocal = "_ * #,##0.00_ ;_ * -#,##0.00_ ;_ * ""-""??_ ;_ @_ " .Rows(1).Copy .Cells .Columns(1).Resize(, 7).Value = arr1 .Cells(iRow 2, 6).Resize(, 2) = "=sum(" & .Columns(6).Address(0, 0) & ")" For i = 1 To Row 1 If Cells(i, 5) = "0" Then Cells(i, 5) = "" End If Next End With DateAndNo = "" End Sub Sub CopyWorksheet(accName As String) Dim sourceWorksheet As Worksheet Dim targetWorksheet As Worksheet Dim wsName As String '设置源工作表 Set sourceWorksheet = ThisWorkbook.Worksheets("凭证抽查(模板)") '设置目标工作表的名称 wsName = "凭证抽查表(" & accName & ")" '检查是否存在同名的目标工作表,如果存在则删除 On Error Resume Next Set targetWorksheet = ThisWorkbook.Worksheets(wsName) On Error GoTo 0 If Not targetWorksheet Is Nothing Then Application.DisplayAlerts = False targetWorksheet.Delete Application.DisplayAlerts = True End If '复制源工作表到同一个工作簿 sourceWorksheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) '获取新复制的工作表的引用 Set targetWorksheet = ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) '重命名新复制的工作表 targetWorksheet.Name = wsName End Sub Sub PrintSheet() ThisWorkbook.Sheets("凭证抽查(模板)").PrintOut Copies:=1 Application.Wait Now TimeSerial(0, 0, 0.5) End Sub

代码解析:

(1)定义一些公共变量。

(2)SelectData过程,根据用户窗体中的各个控件值,产生不同的SQL语句,从“序时账”表中查询数据,一个科目一个科目写入“凭证抽查(模板)”。

(3)Copyworksheet过程,当一个科目数据写入凭证抽查(模板)后,把它复制成以这个科目命名的工作表,接着继续下一个科目。

(4)PrintSheet过程,当一个科目数据写入凭证抽查(模板)后,把它打出来,接着继续下一个科目。

3、自定义函数ShuffleArray

SFunction ShuffleArray(arr As Variant) As Variant Dim numRows As Long Dim randomArr() As Variant Dim shuffledArr() As Variant Dim i As Long, j As Long Dim tempRow As Long '获取数组的行数 numRows = UBound(arr, 1) - LBound(arr, 1) 1 '创建一个与原始数组相同维度的新数组 ReDim randomArr(1 To numRows, 1 To 2) ReDim shuffledArr(LBound(arr, 1) To UBound(arr, 1), _ LBound(arr, 2) To UBound(arr, 2)) '填充随机数列 For i = 1 To numRows randomArr(i, 1) = i LBound(arr, 1) - 1 ' 原始行号 randomArr(i, 2) = Rnd() ' 随机数 Next '按照随机数列的第二列排序 For i = 1 To numRows - 1 For j = i 1 To numRows If randomArr(i, 2) > randomArr(j, 2) Then '交换两行的数据 tempRow = randomArr(i, 1) randomArr(i, 1) = randomArr(j, 1) randomArr(j, 1) = tempRow '交换随机数 tempRow = randomArr(i, 2) randomArr(i, 2) = randomArr(j, 2) randomArr(j, 2) = tempRow End If Next Next '根据排序后的行号复制原始数组到新数组 For i = LBound(arr, 1) To UBound(arr, 1) For j = LBound(arr, 2) To UBound(arr, 2) shuffledArr(i, j) = arr(randomArr(i - LBound(arr, 1) 1, 1), j) Next Next '返回打乱顺序后的新数组 ShuffleArray = shuffledArr End Function

代码解析:

(1)把数组乱序,达到随机抽取凭证的目的。

(2)如果觉得“不够随机”,可以多“随机”几次。

---End---

喜欢就点个、点在看留个言呗!分享一下更给力!感谢!

本文于2023年8月15日首发于本人同名公众号:Excel活学活用,更多文章敬请关注!

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.