Использование VBA кажется мне подходящим способом. Это позволяет вам написать макрос, который позаботится обо всех различных параметрах форматирования и, будем надеяться, будет достаточно простым для того, чтобы ваши финансовые работали сами.
Вы сказали, что вам нужно что-то, что занимает лист или диапазон в Excel. Первый столбец никогда не изменяется, поэтому мы можем сохранить его в макросе, столбцы 3-7 взяты из электронной таблицы, а столбец 8 просто пуст. Это оставляет столбец 2 (квартал / год как QYY) в качестве проблемы. Если квартал / год указан где-то в рабочей книге (например, хранится в ячейке, как имя рабочей таблицы, как часть названия рабочей книги), тогда мы можем просто прочитать его. В противном случае вам нужно будет найти какой-то метод для указания квартала / год при запуске макроса (например, всплывающее диалоговое окно и запросить его у пользователя)
Некоторый простой код (мы будем беспокоиться о том, как его вызвать позже):
Sub ProduceStatePayrollReportFile(rngPayrollData As Range, strCompanyNo As String, _
strQuarterYear As String, strRecordCode As String, strOutputFile As String)
Параметры довольно очевидны: диапазон, в котором хранятся данные, номер компании для столбца 1, квартал / год для столбца 2, фиксированный код для столбца 7 и файл, для которого мы хотим вывести результаты в
' Store the file handle for the output file
Dim fnOutPayrollReport As Integer
' Store each line of the output file
Dim strPayrollReportLine As String
' Use to work through each row in the range
Dim indexRow As Integer
Для вывода в файл в VBA нам нужно получить дескриптор файла, поэтому нам нужна переменная для его сохранения. Мы построим каждую строку отчета в строке строки отчета и будем использовать индекс строки для обработки диапазон
' Store the raw SSN, last name, first name and wages data
Dim strRawSSN As String
Dim strRawLastName As String
Dim strRawFirstName As String
Dim strRawWages As String
Dim currencyRawWages As Currency
' Store the corrected SSN, last name, first name and wages data
Dim strCleanSSN As String
Dim strCleanLastName As String
Dim strCleanFirstName As String
Dim strCleanWages As String
Эти наборы переменных хранят необработанные данные из рабочего листа и очищенные данные для вывода в файл соответственно. Называя их «необработанными» и «чистыми», легче обнаруживать ошибки, когда вы случайно выводите необработанные данные вместо очищенных данных. Нам понадобится изменить необработанную зарплату со строкового значения на числовое значение, чтобы помочь с форматированием
' Open up the output file
fnOutPayrollReport = FreeFile()
Open strOutputFile For Output As #fnOutPayrollReport
FreeFile () получает следующий доступный дескриптор файла, и мы используем его для ссылки на файл
' Work through each row in the range
For indexRow = 1 To rngPayrollData.Rows.Count
' Reset the output report line to be empty
strPayrollReportLine = ""
' Add the company number to the report line (assumption: already correctly formatted)
strPayrollReportLine = strPayrollReportLine & strCompanyNo
' Add in the quarter/year (assumption: already correctly formatted)
strPayrollReportLine = strPayrollReportLine & strQuarterYear
В нашем цикле для работы с каждой строкой мы начинаем с очистки строки вывода и затем добавляем значения для столбцов 1 и 2
' Get the raw SSN data, clean it and append to the report line
strRawSSN = rngPayrollData.Cells(indexRow, 1)
strCleanSSN = cleanFromRawSSN(strRawSSN)
strPayrollReportLine = strPayrollReportLine & strCleanSSN
Часть .Cells(indexRow, 1)
означает только крайний левый столбец диапазона в строке, указанной в indexRow. Если диапазоны начинаются в столбце A (что не обязательно должно быть так), то это просто означает A. Нам нужно позже написать функцию cleanFromRawSSN
' Get the raw last and first names, clean them and append them
strRawLastName = rngPayrollData.Cells(indexRow, 2)
strCleanLastName = Format(Left$(strRawLastName, 10), "!@@@@@@@@@@")
strPayrollReportLine = strPayrollReportLine & strCleanLastName
strRawFirstName = rngPayrollData.Cells(indexRow, 3)
strCleanFirstName = Format(Left$(strRawFirstName, 8), "!@@@@@@@@")
strPayrollReportLine = strPayrollReportLine & strCleanFirstName
Left$(string, length)
усекает строку до заданной длины. Формат изображения !@@@@@@@@@@
форматирует строку длиной ровно десять символов, выравнивание по левому краю (! Означает выравнивание по левому краю) и с пробелами
' Read in the wages data, convert to numeric data, lose the decimal, clean it and append it
strRawWages = rngPayrollData.Cells(indexRow, 4)
currencyRawWages = CCur(strRawWages)
currencyRawWages = currencyRawWages * 100
strCleanWages = Format(currencyRawWages, "000000000")
strPayrollReportLine = strPayrollReportLine & strCleanWages
Мы конвертируем его в валюту, чтобы умножить на 100, чтобы переместить значение центов влево от десятичной точки. Это значительно упрощает использование Format
для генерации правильного значения. Это не даст правильного вывода для заработной платы> = 10 миллионов долларов, но это ограничение формата файла, используемого для отчетности. * * * * * * * * * * * * * * * * * * * *
в форматных планшетах формата с нулями на удивление достаточно.
' Append the fixed code for column 7 and the spaces for column 8
strPayrollReportLine = strPayrollReportLine & strRecordCode
strPayrollReportLine = strPayrollReportLine & CStr(String(29, " "))
' Output the line to the file
Print #fnOutPayrollReport, strPayrollReportLine
Функция String(number, char)
создает вариант с последовательностью number
указанного char
. CStr
превращает вариант в строку. Оператор Print #
выводит в файл без дополнительного форматирования
Next indexRow
' Close the file
Close #fnOutPayrollReport
End Sub
Перейдите к следующему ряду в диапазоне и повторите. Когда мы обработали все строки, закройте файл и завершите макрос
Нам по-прежнему нужны две вещи: функция cleanFromRawSSN и способ вызова макроса с соответствующими данными.
Function cleanFromRawSSN(strRawSSN As String) As String
' Used to index the raw SSN so we can process it one character at a time
Dim indexRawChar As Integer
' Set the return string to be empty
cleanFromRawSSN = ""
' Loop through the raw data and extract the correct characters
For indexRawChar = 1 To Len(strRawSSN)
' Check for hyphen
If (Mid$(strRawSSN, indexRawChar, 1) = "-") Then
' do nothing
' Check for space
ElseIf (Mid$(strRawSSN, indexRawChar, 1) = " ") Then
' do nothing
Else
' Output character
cleanFromRawSSN = cleanFromRawSSN & Mid$(strRawSSN, indexRawChar, 1)
End If
Next indexRawChar
' Check for correct length and return empty string if incorrect
If (Len(cleanFromRawSSN) <> 9) Then
cleanFromRawSSN = ""
End If
End Function
Len
возвращает длину строки, а Mid$(string, start, length)
возвращает length
символов, начиная с string
, начиная с start
. Эту функцию можно улучшить, так как в настоящее время она не проверяет нечисловые данные
Для вызова макроса:
Sub CallPayrollReport()
ProduceStatePayrollReportFile Application.Selection, "1234560007", "109", "01", "C:\payroll109.txt"
End Sub
Это самый простой способ назвать это. Диапазон - это то, что пользователь выбрал на активной рабочей таблице в активной рабочей книге, а остальные значения жестко запрограммированы. Пользователь должен выбрать диапазон, который он хочет вывести в файл, затем перейдите в Инструменты> Макрос> Выполнить и выберите CallPayrollReport
. Чтобы это работало, макрос должен быть частью рабочей книги, содержащей данные, или другой книгой, которая была загружена до того, как пользователь вызовет макрос.
Кто-то должен будет изменить жестко закодированное значение квартала / года, прежде чем будет сгенерирован отчет за каждый квартал. Как указывалось ранее, если квартал / год уже сохранен где-то в рабочей книге, лучше прочитать его, а не жестко кодировать его
Надеюсь, что это имеет смысл и имеет некоторое значение