определение LastRow в VBA - PullRequest
       21

определение LastRow в VBA

0 голосов
/ 03 апреля 2020

Я пытаюсь экспортировать данные из таблицы Excel в шаблон счета Excel. Код VBA, который у меня есть, рассматривает каждую строку как отдельный счет-фактуру и, следовательно, создает разные рабочие книги для каждой строки. Таким образом, в случае, если у меня есть 1 счет-фактура, в которой есть 3 продукта, этот код рассматривает каждый продукт (строку) как отдельный счет-фактуру, что является неправильным. Я хочу изменить его таким образом, чтобы, если номер счета-фактуры (PiNo) повторялся в следующей строке, это означает, что следующий продукт (строка) принадлежит только вышеупомянутому счету-фактуре. Я новичок в VBA, поэтому я взял код с другого сайта.

Вот код: -

   Private Sub CommandButton1_Click()
   Dim customername As String
   Dim customeraddress As String
   Dim invoicenumber As Long
   Dim r As Long
   Dim mydate As String
   Dim path As String
   Dim myfilename As String
   lastrow = Sheets(“CustomerDetails”).Range(“H” & Rows.Count).End(xlUp).Row
   r = 2
   For r = 2 To lastrow

   ClientName = Sheets("CustomerDetails").Cells(r, 6).Value
   Address = Sheets("CustomerDetails").Cells(r, 13).Value
   PiNo = Sheets("CustomerDetails").Cells(r, 5).Value
   Qty = Sheets("CustomerDetails").Cells(r, 9).Value
   Description = Sheets("CustomerDetails").Cells(r, 12).Value
   UnitPrice = Sheets("CustomerDetails").Cells(r, 10).Value
   Salesperson = Sheets("CustomerDetails").Cells(r, 1).Value
   PoNo = Sheets("CustomerDetails").Cells(r, 3).Value
   PiDate = Sheets("CustomerDetails").Cells(r, 4).Value
   Paymentterms = Sheets("CustomerDetails").Cells(r, 7).Value
   PartNo = Sheets("CustomerDetails").Cells(r, 8).Value
   Shipdate = Sheets("CustomerDetails").Cells(r, 14).Value
   Dispatchthrough = Sheets("CustomerDetails").Cells(r, 15).Value
   Modeofpayment = Sheets("CustomerDetails").Cells(r, 16).Value
   VAT = Sheets("CustomerDetails").Cells(r, 17).Value

   Workbooks.Open ("C:\Users\admin\Desktop\InvoiceTemplate.xlsx")
   ActiveWorkbook.Sheets("InvoiceTemplate").Activate
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“Z8”).Value = PiDate
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“AG8”).Value = PiNo
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“AN8”).Value = PoNo
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“B16”).Value = ClientName
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“B17”).Value = Address
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“B21”).Value = Shipdate
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“K21”).Value = Paymentterms
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“T21”).Value = Salesperson
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“AC21”).Value = Dispatchthrough
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“AL21”).Value = Modeofpayment
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“B25”).Value = PartNo
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“J25”).Value = Description
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“Y25”).Value = Qty
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“AF25”).Value = UnitPrice
   ActiveWorkbook.Sheets("InvoiceTemplate").Range(“AL39”).Value = VAT

   path = "C:\Users\admin\Desktop\Invoices\"
   ActiveWorkbook.SaveAs Filename:=path & PiNo & “.xlsx”
   myfilename = ActiveWorkbook.FullName
   ActiveWorkbook.Close SaveChanges:=True

   Next r

   End Sub

"H" - столбец продукта, а данные начинаются со строки 2. Строка 1 - это заголовки.

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

1 Ответ

0 голосов
/ 05 апреля 2020

Есть несколько областей, которые нужно учитывать, когда речь идет о том, чего вы хотите достичь, по сравнению с вашим текущим кодом. Я изложу это ниже в произвольном порядке и предоставлю пример кода, который поможет вам достичь того, чего вы хотите.

  1. Ваш код для создания, сохранения и закрытия новой книги содержится в пределах твой for л oop. Это означает, что если мы предполагаем, что у вас есть 3 продукта для добавления в ваш счет, ваш код откроет InvoiceTemplate.xlsx с рабочего стола в общей сложности 3 раза , а также сохранит его и закроет с помощью PiNo имя 3 раза . Чтобы это исправить, вам нужно переместить код, чтобы открыть книгу до запуска For l oop, и переместить код SaveAs после символа l oop, чтобы сохранить и закрыть книгу только один раз.
  2. Ваш код использует .activate и почти полностью ссылается на ActiveWorkbook (если вы не объявите рабочую книгу, она примет ActiveWorkbook). Этого следует избегать, и вы должны явно определять объект, который вы используете вместо этого (почему вы должны это делать, это уже обсуждалось довольно подробно - вы можете прочитать об этом здесь: Как избежать использования Select в Excel .
  3. Вы объявили несколько переменных, которые вы на самом деле не используете. Либо используйте их, либо удалите их для удаления кода.
  4. Вы не объявили переменные, хранящие значения из ваш лист (в начале вашего для l oop), что означает, что они автоматически создаются как тип данных Variant, который не очень эффективен.
  5. for l oop записывает переменные установить ссылки на ячейки, что означает, что даже если мы исправим все другие проблемы, код будет просто перезаписывать одни и те же ячейки с каждой итерацией l oop. Это можно решить, задав значение строки в переменной и увеличивая его с каждой l oop итерация (при условии, что именно так должен быть завершен шаблон).

В качестве дополнительной точки; используется более длинная, но не более Описательные имена переменных могут значительно облегчить жизнь при отладке ошибок, особенно когда вы новичок в VBA, поэтому вы можете рассмотреть это со всеми своими переменными. Например, LoopRow ИЛИ RowCounterForLoop вместо r и InvoiceTemplatePath ИЛИ SavedInvoicesPath вместо path.

Вот пример кода чтобы дать вам представление о том, как реализовать некоторые изменения с учетом вышеуказанных пунктов, в нем мы будем использовать только переменную PiNo (но просто скопируем изменения в каждую из других соответствующих переменных):

Private Sub CommandButton1_Click()

Dim LastRow As Long     
Dim RowCounterForLoop As Long 
Dim InvoiceTemplateRowCounter as Long
Dim DesktopFilePath As String
Dim SavedInvoiceFilePath As String

Dim PiNo As String  

LastRow = ThisWorkbook.Sheets("CustomerDetails").Range("H" & Rows.Count).End(xlUp).Row
InvoiceTemplateRowCounter = 8

DesktopFilePath = "C:\Users\admin\Desktop\"
SavedInvoiceFilePath = "C:\Users\admin\Desktop\Invoices\"

Workbooks.Open (DesktopFilePath & "InvoiceTemplate.xlsx")

For RowCounterForLoop = 2 To lastrow       'I've removed the previous assignment of 2 to RowCounterForLoop as it is assigned on this line.

    PiNo = ThisWorkbook.Sheets("CustomerDetails").Cells(r, 5).Value        'I've added ThisWorkbook before the Sheet which explicitly defines the code to affect the workbook the code is running on. It also uses a variable instead of number to allow dynamic referencing to the range. 

    Workbooks("InvoiceTemplate.xlsx").Sheets("InvoiceTemplate").Range("AG" & InvoiceTemplateRowCounter).Value = PiNo        'I've added Workbooks("InvoiceTemplate.xlsx") to explicitly run this code on that workbook which avoids using ActiveWorkbook.
    InvoiceTemplateRowCounter = InvoiceTemplateRowCounter + 1
Next RowCounterForLoop 

Workbooks("InvoiceTemplate.xlsx").SaveAs Filename:=SavedInvoiceFilePath & PiNo & ".xlsx" 
Workbooks("InvoiceTemplate.xlsx").Close SaveChanges:=False    'The file is saved on the previous line so this will avoid saving again and pop up prompts etc. 

End Sub

Вышесказанное не исправит все, и есть лучшие и более эффективные способы достижения того, чего вы хотите, но оно дает ответ на ваш вопрос.

Возможно, вы захотите рассмотреть следующее для дальнейшего улучшения вашего кода :

  1. Использование массивов для хранения данных и их записи в новую рабочую книгу. (Это может быть довольно сложно, в зависимости от ваших навыков использования массивов с VBA)
  2. Чтобы ввести PiNo в каждую строку (если имеется более 1 продукта), вы можете использовать метод Range.FillDown (в зависимости от как именно работает ваш лист), о котором вы можете прочитать Здесь.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...