Здравствуйте уважаемые форумчане. Давно волновал вопрос, но до последнего времени остро не стоял - Как скопировать из Excel в другие приложения только выделенные ячейки?
Честно, уделил поиску ответа на данный вопрос пару дней (не полных конечно же ) Из того, что находится - только темы "...копировать только отфильтрованные ячейки..." и "...скопировать без скрытых ячеек..." и сводится к использованию сочетания Ctrl+G и выделение только видимых ячеек. Нашлась только одна тема на хабре и то без нужного мне ответа. Данные решения не подходят так как ячейки не скрыты - они видны, и просто не попадают в селекшон
Я понимаю что Excel внутри себя имеет некоторые "расширенные" свойства буфера данных, и при копировании только выделенных ячеек и вставки их на этот/другой лист - все происходит как задумано, но стоит тут же вставить эти данные например в блокнот - магии не происходит и туда вставляются все данные находящиеся между выделенными ячейками.
У меня возникло идея только 2 способов реализации этого: 1. Проходится циклом по всем выделенным ячейкам, с копированием данных в какой-нибудь массив и дальнейшем переносом этих данных в клипборд (смущает скорость выполнения особенно при больших выборках) 2. После стандартного копирования выделенных ячеек - вставка их на временный лист/диапазон - с последующим повторным копированием ячеек (уже без пропусков) с этого диапазона в клипборд (смущает наличие "временного листа/диапазона" особенно при больших выборка стремящихся к максимальному значению столбцов/строк)
Может кто-нибудь наставить на путь истинный и подсказать заветную функцию/параметр/свойство если таковой имеется в VBA в нативном виде ну или подсказать более легкий алгоритм чем предложенные выше?
Я может не до конца понял, копирование выделенных ячеек на свободный участок в эксель (Например в ячейку AA1), а далее уже копирование в другое приложение Range("AA1").CurrentRegion.Copy
Ham13 написал: Я может не до конца понял, копирование выделенных ячеек на свободный участок в эксель (Например в ячейку AA1), а далее уже копирование в другое приложение Range("AA1").CurrentRegion.Copy
Суть вы правильно поняли, и один из путей решения тоже (я указал этот способ под номером 2) Так как проект планируется для использования условными "бабушками", которым трудно объяснить даже такую простую последовательность действий - меня интересует возможность (если таковая есть) в естественном виде скопировать/вставить - хоть с помощью волшебного сочетания клавиш, хоть с помощью неизвестного мне параметра/функции/и т.д. в VBA (c реализацией в VBA у меня проблема не стоит - оба варианта за часок -другой можно накидать, но не дает это сделать мысль, что возможно существует другой нативный или более оптимальный способ)
Еще раз здравствуйте. К сожалению не нашлось ответов на мой вопрос. Видимо действительно не существует подобного нативного решения
Однако как и обещал прикладываю вариант своего решения (из 1 сообщения это вариант №2) Для начала поясню какой была задача: Имеется датасет с определенной последовательностью полей, и для разных "внешних" приложений требуется различные данные из этого датасета, где-то только 1,2,4 и 6 поля (столбцы) где-то 2, 5 и 7 и т.д. Было сделано несколько кнопок для каждого случая и при выборе необходимой строки выделялись и копировались необходимые столбцы ну а дальше проблема изложена в первом сообщении
Пример выбора необходимых полей и вызова процедуры рекопирования (на каждую кнопку можно вешать свой набор полей)
Сама процедура рекопирования тут можно пользоваться одним из двух методов и у обоих есть свои минусы (см. в комментарии внутри)
Код
Sub copy_to()
Dim cc As Integer
cc = ActiveSheet.UsedRange.Rows.Count
'особенности: вставляет не переключаясь на выделенную ячейку, копирует форматы, может вставлять после вырезания range.cut
ActiveSheet.Paste Range("B" & cc + 100)
'особенности: вставляет переключаясь на выделенную ячейку, копирует только значения, не вставляет вырезаные значения range.cut
'ActiveSheet.Range("B" & cc + 100).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
Range("B" & cc + 100).CurrentRegion.Copy
End Sub
Минусов у этого решения полно (о них я писал и начале, и в комментариях) но меня локально пока всё устраивает В общем может кому-то поможет
P.S. ...и все интересно, есть ли другой более элегантный (и быстрый) способ? ....
так как смысл задачи не очень понимаю, то просто скажу 1. Integer - это число до 32 767, а строк на листе может быть значительно больше, поэтому всё же лучше Long 2. Последнюю строку более правильнее определять вот так cc = ActiveSheet.UsedRange.Rows.Count + ActiveSheet.UsedRange.Row, а не просто cc =ActiveSheet.UsedRange.Rows.Count 3. Вы всё время копируете куда-то ниже и это куда-то ниже может иногда закончится и вы выйдите за приделы листа (сс +100). Как совет копировать куда-нибудь в одно место с предварительной очисткой от старых данных. Возможно даже на специально созданный лист. А куда вы копируете данные из Excel ? В Блокнот?
New, спасибо за ценные замечания 1. Бесспорно Long для этих целей подойдет больше 2. Действительно, если не используется вначале листа какое либо количество строк есть большая вероятность затереть перекопированием начальные данные - тут как говорится пока не попадешь в просак - проблему не увидишь 3. В моем проекте первичный датасет я получаю каждый раз новый из БД (с предварительной очисткой и другими действиями) поэтому пошел по пути наименьшего сопротивления. Но честно-честно меня этот вариант очень коробил именно из-за описанных вами вещей (я это упоминал в первом посте). А реализовывать с доп листом (который надо скрывать от посторонних глаз) - просто в виду не нужности - не хочется
Что касается копирования - в любое место - блокнот, гуглшит, яндекс таблицы и даже внутри MS - тот же ворд, поверпоинт, аксесс и д.р. - везде не работает копирование выделенных (разнесенных) ячеек
Все верно, в MS Word вставился весь диапазон начиная с А5 до АА5 (27 полей) - просто у вас вставленная таблица за границы листа вышла, а должны было вставится эти диапазоны "A" ",B:F" ",K" ",M" ",V" ",AA" (10 выделенных полей)
PS Как прикрепить картинку чтобы в сообщении была? что-то совсем туплю
Вообще не понимаю, что у Вас там происходит. Неужели такой код скопирует и вставит в другое приложение все ячейки, а не только видимые среди выделенных?
Код
Selection.SpecialCells(xlCellTypeVisible).Copy
Цитата
Viktor Vavilov написал: в MS Word вставился весь диапазон
а выделили Вы до копирования какой диапазон? Были ли скрытые ячейки среди выделенных?
Дмитрий(The_Prist) Щербаков написал: а выделили Вы до копирования какой диапазон? Были ли скрытые ячейки среди выделенных?
Выделялся до копирования НЕ весь тот диапазон, который вставился - в этом собственно и вся проблема. И ячейки/столбцы/строки не были скрыты. Выше был код выделения и копирования (он есть и в файле примера).
Но оно (выделение) может быть вообще рандомное. Суть такова, что при выделении ячеек A1 и С1 их копировании, в Excel вставится A1C1, а в остальные приложения A1B1C1, также и со столбцами - при выделении A1 и A3 - вставится в Excel A1A3, а в остальные приложения A1A2A3.
Попробовал ваше предложение, и ничего не получилось (см приложенный скрин). Честно, мне уже начинает казаться, что я единственный с такой проблемой и у всех остальных это всё работает
Код
Sub Copy_to_1()
Dim rr As Long
rr = Selection.Row
Range("B" & rr & ":F" & rr & ",K" & rr & ",A" & rr & ",M" & rr & ",V" & rr & ",AA" & rr).Select
Selection.SpecialCells(xlCellTypeVisible).Copy
End Sub
Viktor Vavilov написал: я единственный с такой проблемой и у всех остальных это всё работает
так и есть. У всех вставляется ровно то, что было скопировано. Посмотрите, нет ли у Вас каких-то сторонних утилит, которые перехватывают буфер обмена. Попробуйте отключить вообще все надстройки от Excel и проверить работу копирования-вставки без них.
Цитата
Viktor Vavilov написал: Excel внутри себя имеет некоторые "расширенные" свойства буфера данных, и при копировании только выделенных ячеек и вставки их на этот/другой лист
внутренний буфер офиса влияет, если можно так сказать, только на мета-данные(форматы ячеек и т.п.). Но это не относится к проблеме - если скопировали только ячейку А1 и С1 - то только их данные и попадают в буфер.
Мой косяк - изначально много букафф в стартовом сообщении, включая что-то про скрытые и т.п. Не осилил я все это в полной мере. А может просто затупил. Поэтому экспериментировал именно со скрытыми(копируя только видимые), а не произвольно выделенными. А с произвольно выделенными да, есть проблема. И вряд ли есть решение "из коробки".
Дим, у меня ощущение, что мы немного про разные проблемы говорим. Лист Excel. В А1 введено 1, В В1 - 2, в С1 - 3 Выделяем А1, зажимаем Контрл, выделяем С1. Жмем Контрл+С. Переходим в Ворд или в Блокнот Жмем Контрл+v Вставляются 1 2 3 Для проверки снова переходим в Excel, жмем Контрл+v Вставляются 1 3
Пока писал, уже разобрались. С непониманием ))), не с проблемой (((
Выделить ячейки, запустить макрос, вставить в блокнот Ctrl+V
Код
Sub CopySelectionOnly_ToClipBoard()
Dim rng As Range, cl As Range
Dim tx$
Set rng = Selection
For Each cl In rng
tx = tx & vbTab & cl.Value
Next cl
CreateObject("htmlfile").parentWindow.clipboardData.SetData "Text", Mid$(tx, 2) & vbCrLf
End Sub
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Извиняюсь, хотел подробнее описать проблему и что ранее уже было сделано, чтобы не предлагались в ответ ранее выполненные действия, а эффект оказался в точности да наоборот
Jack Famous, спасибо! Но есть небольшое НО, при выделении данных из разных СТРОК, они будут разделятся табуляцией как будто это разные СТОЛБЦЫ. Но переделать для отслеживания смены строки и вставки vbCrLf - не составит труда. сделано см код ниже
Скрытый текст
Код
Sub CopySelectionOnly_ToClipBoard()
Dim rng As Range, cl As Range
Dim tx$
Dim rr As Long
Set rng = Selection
For Each cl In rng
If rr = cl.Row Or rr = 0 Then
tx = tx & vbTab & cl.Value
Else
tx = tx & vbCrLf & cl.Value
End If
rr = cl.Row
Next cl
CreateObject("htmlfile").parentWindow.clipboardData.SetData "Text", Mid$(tx, 2) & vbCrLf
End Sub
В итоге те два варианта упомянутые мной в первом посте и оказались решением данной проблемы, жаль что в Excel есть такой баг... а может быть фича Всем огромное спасибо!
Viktor Vavilov: при выделении данных из разных СТРОК, они будут разделятся табуляцией как будто это разные СТОЛБЦЫ
ну я ж пример делал, а не рабочий комбайн Вы всё правильно поняли, но я не уверен, что ваш код будет корректно работать с различными вариантами выделенных диапазонов. Потестируйте хорошенько - что-то меня смущает… Как минимум, второй аргумент в Mid$(tx, 2)будет 3, если tx начинается с vbCrLf
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄