Установить пункт назначения вставки как последнюю использованную строку на другом листе - PullRequest
0 голосов
/ 18 апреля 2020

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

Цели: скопируйте непостоянную группу ячеек (например, d69, d70, d72, d73, g92, g93 и т. Д. c) и вставьте их в другой (на этот раз непрерывный) диапазон ячеек на другой лист, в строке ниже последней использованной строки.

Контекст: я создаю базу данных информации, заполненной из «Формы пользователя» на листе 1. Когда пользователь нажимает кнопку с макросом, данные копируются на лист 2 в качестве новой записи.

Мысли: я думал, что может быть проще установить переменную на значение последней ячейки, использованной на листе 2, а затем использовать что-то вроде диапазона ("b" и "aa"). Pastespecial xlPasteValues ​​для каждой ячейки, которую нужно скопировать. Однако я не могу понять это или найти то, что мне нужно сделать, чтобы достичь этого. Любая помощь будет принята с благодарностью! Большое спасибо.

Если у вас есть какие-либо вопросы или вам нужны разъяснения, дайте мне знать! Спасибо!

См. Ссылку на документ ниже:

Рабочий файл

Ответы [ 2 ]

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

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

Предполагается, что ваши вспомогательные столбцы находятся на новом листе с именем "Помощник" , ввод данных на лист с именем "BBU Quote Entry" и данные перемещаются в BBU База данных котировок .

Sub BBUEntryToDatabaseUsingHelper()

Dim UserInputsArray() As Variant
Dim HelperRange As Range
Dim Destination As Range
Dim LastBBUDatabaseRow As Long
Dim LastHelperRow As Long

With ThisWorkbook.Sheets("Helper")
    LastHelperRow = .Cells(Rows.Count, 2).End(xlUp).Row
    Set HelperRange = .Range("B2:B" & LastHelperRow)
End With

UserInputsArray() = HelperRange.Value

With ThisWorkbook.Sheets("BBU Quote Database")
    LastBBUDatabaseRow = .Cells(.Rows.Count, 2).End(xlUp).Row + 1
    Set Destination = .Cells(LastBBUDatabaseRow, 2)
    Set Destination = Destination.Resize(1, UBound(UserInputsArray, 1))
    Destination.Value = Application.Transpose(UserInputsArray)
End With

End Sub

Форма ввода:

Input sheet form with completed values

Вспомогательные столбцы:

First 11 values in helper columns

Это работает просто путем ссылки на соответствующую ячейку из входного листа на вспомогательном листе.

Например, значение "Компания-заказчик" находится в ячейке D6 на листе BBU Quote Entry, поэтому столбец помощника имеет ='BBU Quote Entry'!D6

. Для ссылки "Опасный" я нашел ячейку, которой управляют формы. OptionButtons связан с (E74 на листе BBU Quote Entry и используется =IF('BBU Quote Entry'!E74 = 1, "Hazardous",IF('BBU Quote Entry'!E74 = 2,"Non-Hazardous","Not Specified"))

Поскольку у вас есть пользовательское форматирование, например, «Желаемый зазор» "значение форматирует входные данные как #### Inches, ссылка возвращает только введенное значение, а не форматирование - вы можете посмотреть дальше, чтобы решить это, но в то же время я добавил строку после ссылки на значение, например, для" Желаемого разрешения "=('BBU Quote Entry'!D15) & " Inches".

Если данные хранятся в правильном порядке для вывода на лист «База данных котировок BBU», мы можем просто поместить диапазон из листа «Помощник» непосредственно в Array(), и затем записать массив в правильный диапазон в «База данных котировок BBU».

Вот как выглядит результат:

enter image description here


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

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

После того, как вы прокомментировали разъяснение и добавили Workbook к вашему вопросу, я отредактировал этот ответ, чтобы отразить эти обновления.

Предполагая, что вы знаете адрес ячейки для каждого значения в sheet1 И адрес ячейки постоянен.

Я написал Subroutine, чтобы захватить значения вашей формы BBU Quote Entry и записать их в ваш диапазон BBU Quote Database. Я добавил это к Module4.

Следует отметить, что код работает только с разделом Основы c Информация вашей формы И 2 кнопками выбора для Hazardous или Non-Hazardous с использованием функция ReturnFormControlCaption. Вы можете поместить в жесткие дворы для остальных данных (более или менее просто скопировать вставить, переименовать переменные, настроить значения диапазона и, конечно, добавить переменные в массив).

Sub BBUEntryToDatabase()

Dim CustCompany As String
Dim CustName As String
Dim CustLocation As String
Dim CMTRep As String
Dim QuoteNo As String
Dim QuoteDate As String
Dim Hazard as String

With ThisWorkbook.Sheets("BBU Quote Entry")

    CustCompany = .Range("D6").Value
    CustName = .Range("D8").Value
    CustLocaction = .Range("D10").Value
    CMTRep = .Range("G6").Value
    QuoteNo = .Range("G8").Value
    QuoteDate = .Range("G10").Value
    Hazard = ReturnFormControlCaption("BBU Quote Entry", "HazardousButton", "NotHazardousButton")

End With

Dim BBUArray As Variant
'The Array is assigned in order of your headings on "BBU Quote Database" sheet
BBUArray = Array(QuoteNo, CustCompany, CustName, CustLocation, CMTRep, QuoteDate, _
 "Clearance", "Height", "Material", "Density", Hazard) 

Dim Destination As Range
Dim LastRow As Long

    With ThisWorkbook.Sheets("BBU Quote Database")
        LastRow = .Cells(.Rows.Count, 2).End(xlUp).Row + 1
        Set Destination = .Cells(LastRow, 2)
        Set Destination = Destination.Resize(1, UBound(BBUArray, 1) + 1) ' + 1 as the array is 0 based (whereas columns start at 1).
        Destination.Value = BBUArray
    End With

End Sub

Вот скриншот моей записи данных

Basic Information section of user input sheet form

И вывод на "BBU Quote Database" (после 3 теста с одинаковыми входами)

Output of VBA code on database sheet

Я не очень знаком с Form Controls, как обычно использую ActiveX Controls который я нахожу немного более легким в использовании с VBA - я предполагаю, что, возможно, есть более чистый способ работы с OptionButtons.

Функция ReturnFormControlCaption():

Function ReturnFormControlCaption(ByVal SheetNameTheControlIsOn As String, ByVal FirstFormControlName As String, _
    Optional ByVal SecondFormControlName As String, Optional ByVal ThirdFormControlName As String, _ 
    Optional ByVal FourthFormControlName As String, Optional ByVal FifthFormControlName As String, _ 
    Optional ByVal SixthFormControlName As String) As String

With ThisWorkbook.Sheets(SheetNameTheControlIsOn)

    If SecondFormControlName = "" Then
        If .Shapes(FirstFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FirstFormControlName).OLEFormat.Object.Caption
        Else
            ReturnFormControlCaption = "Not Specified"
        End If
    ElseIf ThirdFormControlName = "" Then
        If .Shapes(FirstFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FirstFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(SecondFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(SecondFormControlName).OLEFormat.Object.Caption
        Else
            ReturnFormControlCaption = "Not specified"
        End If
    ElseIf FourthFormControlName = "" Then
        If .Shapes(FirstFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FirstFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(SecondFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(SecondFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(ThirdFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(ThirdFormControlName).OLEFormat.Object.Caption
        Else
            ReturnFormControlCaption = "Not specified"
        End If
     ElseIf FifthFormControlName = "" Then
        If .Shapes(FirstFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FirstFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(SecondFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(SecondFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(ThirdFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(ThirdFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(FourthFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FourthFormControlName).OLEFormat.Object.Caption
        Else
            ReturnFormControlCaption = "Not specified"
        End If
    ElseIf SixthFormControlName = "" Then
        If .Shapes(FirstFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FirstFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(SecondFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(SecondFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(ThirdFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(ThirdFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(FourthFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FifthFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(FifthFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FifthFormControlName).OLEFormat.Object.Caption
        Else
            ReturnFormControlCaption = "Not specified"
        End If
    Else
        If .Shapes(FirstFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FirstFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(SecondFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(SecondFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(ThirdFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(ThirdFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(FourthFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FifthFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(FifthFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(FifthFormControlName).OLEFormat.Object.Caption
        ElseIf .Shapes(SixthFormControlName).OLEFormat.Object.Value = 1 Then
            ReturnFormControlCaption = .Shapes(SixthFormControlName).OLEFormat.Object.Caption
        Else
            ReturnFormControlCaption = "Not specified"
        End If
    End If
End With

End Function

Чтобы кратко объяснить функцию, вы передаете string переменные для соответствующего имени рабочего листа и, по крайней мере, одно (до шести) имя (я) элемента управления формы.

Длинные и вложенные If...ElseIf...Else операторы сначала устанавливают, до какой аргумент был включен. Затем в зависимости от того, какой аргумент является первым пустым или "" значением, он выполняет следующий оператор If...ElseIf...Else, чтобы определить в этом случае, какой OptionButton выбран, а затем возвращает .Caption этого OptionButton.

Если не выбран ни один из оцениваемых OptionButton, возвращается «Не указано».

Примечание: эта функция будет работать для определения того, какой CheckBox проверен НО , если в переданных вами аргументах выбрано более одного, будет возвращено только .Caption первого CheckBox, который проверен. С некоторой модификацией вы могли бы заставить функцию работать для обоих типов, включая все проверяемые CheckBox.


Чип Пирсон имеет отличную информацию о массивах и о том, как их использовать. Вы можете прочитать о них на его сайте по адресу www.cpearson.com или, в частности, о том, что мы сделали здесь с массивами , в этой статье на его сайте

...