Excel VBA Как определить, было ли что-то вставлено на листе

#vba #excel

#vba #excel #копировать-вставить

Вопрос:

Начну с того, что мой опыт работы с Excel и VBA ограничен тем, что я видел в школе. У меня есть опыт программирования, но на других языках.

У меня есть файл, который я получаю каждую неделю. Структура этого файла всегда одинакова: идентификатор, имя, дата, значение от 1 до 4, не относящиеся к делу данные.

Эти данные выбираются с помощью кнопки «выбрать все» (верхний левый угол листа, маленький треугольник под именем ячейки в MS Excel 2013), а затем копируются в другой файл по умолчанию, который перерабатывает данные для отображения и фильтрации их на разных листах на основе значения 1-4 и даты.

Мой вопрос: как мне определить, когда данные были / вставлены? Я попробовал рабочий лист.Событие изменения, но команда вставки (CTRL V) не запускает событие изменения. Кроме того, как будут скопированы данные? Будет ли он обновлять строку за строкой, ячейку за ячейкой (в каком направлении), …? Я знаю, что могу легко найти ответ на последний вопрос, отладив его, как только я смогу обнаружить команду копирования, но вы никогда не знаете, знает ли кто-нибудь ответ.

Есть ли другой, более простой (или лучший) способ сделать это?

При необходимости можно предоставить дополнительные данные и информацию.

Спасибо за вашу помощь.

РЕДАКТИРОВАТЬ: «… копируется / копируется?» изменено на вставлено, как и должно было быть.

Комментарии:

1. Почему вы хотели бы знать, были ли скопированы данные? Есть ли какая-то конкретная причина? Чего вы хотите достичь? Вы хотите заполнить эти данные в другую книгу / рабочий лист?

2. Вы видели это: siddharthrout.com/2011/08/15/vba-excelallow-paste-special-only ?

3. @MaciejLos Причина в том, что люди, которые будут использовать файл, получают большой список данных каждую неделю. Они вставят этот список в первый рабочий лист файла, над которым я сейчас работаю, и мне нужен файл, чтобы затем отфильтровать соответствующие данные и отобразить их на других рабочих листах на основе определенных значений в строке. RE: ваш другой комментарий: Я открыл его перед перерывом, но не закончил читать. В настоящее время я пробую это, и, похоже, он делает то, что я хочу. Опубликует ответ, если это произойдет.

4. Пожалуйста, посмотрите мой ответ 😉

5. @Nahbyr Вы говорите: «Я пробовал рабочий лист. Событие изменения, но команда вставки (CTRL V) не запускает событие изменения. » Это вызывает глубокое беспокойство, если это то, что вы испытываете. Вау! Какие настройки, версии, моды, дополнения и т. Д. вы собираетесь туда, чтобы это было правдой ?!

Ответ №1:

 Private Sub Worksheet_Change(ByVal Target As Range)
  Dim UndoList As String

  '~~> Get the undo List to capture the last action performed by user
  UndoList = Application.CommandBars("Standard").Controls("amp;Undo").List(1)

  '~~> Check if the last action was not a paste nor an autofill
  If Left(UndoList, 5) = "Paste" Then
    'Do stuff
  End If
End Sub
  

Это сделало свое дело. Для тех, кому нужно что-то подобное и кто знает размер своего списка, ответ @MaciejLos также сработает.

Ответ №2:

Событие Worksheet_Change выполнит задание, если вы добавите формулу в ячейку, которая никогда не будет перезаписана. Допустим, ваши данные вставлены в ячейку A1 и занимают 5 столбцов. Итак, введите приведенную ниже формулу в 6. столбец и строку 1.

 =COUNTBLANK(A1:A1048576)
  

Теперь вы можете обрабатывать / обнаруживать событие вставки 😉

Комментарии:

1. Это сработало бы, если бы не тот факт, что я не знаю, насколько большим будет список данных, который они будут импортировать. Я нашел решение своей проблемы по ссылке, которую вы прислали ранее. Опубликует код.

Ответ №3:

Мне не удалось добавить это в качестве комментария, поэтому я публикую это как ответ. ответ @Nahbyr работает, когда в Excel в качестве предпочтительного языка задан «английский», иначе он не будет работать.

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

Это функция, которую я написал, чтобы проверить, было ли последнее действие действием вставки, вставки или специальной вставки.

 Public Function LastActionPaste() As Boolean

' The function LastActionPaste checks if the last action made was a paste action, if so it returns TRUE
' Otherwise it returns FALSE

Dim UndoList As String

LastActionPaste = False
UndoList = Application.CommandBars(11).Controls(14).List(1)

'~~> Check if the last action was a paste or paste special
If UndoList = "Paste" Or UndoList = "Paste Special" Then
    
    LastActionPaste = True
    
End If

End Function
  

Обновить

Таким образом, очевидно, что индексы не совпадают при разных установках Excel, будь то потому, что это разные версии или что-то еще…

Таким образом, даже если предпочитаемый язык не английский, панели команд.Название по-прежнему на английском, НО элементы управления.Заголовок меняется…

Теперь я надеюсь, что индексы элементов управления не изменятся, иначе это не сработает.

Поэтому я изменил функцию следующим образом, чтобы она работала:

 Public Function LastActionPaste() As Boolean

' The function LastActionPaste checks if the last action made was a paste action, if so it returns TRUE
' Otherwise it returns FALSE

Dim UndoList As String
Dim barFound As Boolean
Dim index As Long

LastActionPaste = False
index = 1
barFound = False

Do While barFound = False
    
    If Application.CommandBars(index).name = "Standard" Then
        
        barFound = True
        
        Else
        
        index = index   1
        
    End If
    
Loop

UndoList = Application.CommandBars(index).Controls(14).List(1)

'~~> Check if the last action was a paste or paste special
If UndoList = "Paste" Or UndoList = "Paste Special" Then
    
    LastActionPaste = True
    
End If

End Function