В Excel нет встроенных средств обоюдного переноса данных (например поменять местами значения А1 и В1 одним кликом). Как это реализовать макросом?
Как это должно работать (один из вариантов): Выделяю с нажатым Ctrl два диапазона - ПКМ - Поменять местами. Теперь содержимое ячейки А1 находится в В1 и наоборот. Спасибо.
В Excel нет встроенных средств обоюдного переноса данных (например поменять местами значения А1 и В1 одним кликом). Как это реализовать макросом?
Как это должно работать (один из вариантов): Выделяю с нажатым Ctrl два диапазона - ПКМ - Поменять местами. Теперь содержимое ячейки А1 находится в В1 и наоборот. Спасибо.
============================================================== Стоит задача с помощью макроса в Excel поменять местами выделенные ячейки (ну или выделенные строки/столбцы), при этом ячейки(или строки/столбцы) не являются смежными, а - произвольно выбранными пользователем. EducatedFool VBA Developer --------------------------------------------------------------------------------
Вот вам макрос:
[vba]
Код
Sub SwapRanges() Dim ra As Range: Set ra = Selection msg1 = "Надо выделить ДВА диапазона ячеек одинакового размера" msg2 = "Надо выделить 2 диапазона ячеек ОДИНАКОВОГО размера" If ra.Areas.Count <> 2 Then MsgBox msg1, vbCritical, "Ошибка": Exit Sub If ra.Areas(1).Count <> ra.Areas(2).Count Then MsgBox msg2, vbCritical, "Ошибка": Exit Sub Application.ScreenUpdating = False arr2 = ra.Areas(2).Value ra.Areas(2).Value = ra.Areas(1).Value ra.Areas(1).Value = arr2 End Sub
Добавлю от себя - переносятся только значения, формулы затираются, форматирование остаётся старым.
Из закромов :
============================================================== Стоит задача с помощью макроса в Excel поменять местами выделенные ячейки (ну или выделенные строки/столбцы), при этом ячейки(или строки/столбцы) не являются смежными, а - произвольно выбранными пользователем. EducatedFool VBA Developer --------------------------------------------------------------------------------
Вот вам макрос:
[vba]
Код
Sub SwapRanges() Dim ra As Range: Set ra = Selection msg1 = "Надо выделить ДВА диапазона ячеек одинакового размера" msg2 = "Надо выделить 2 диапазона ячеек ОДИНАКОВОГО размера" If ra.Areas.Count <> 2 Then MsgBox msg1, vbCritical, "Ошибка": Exit Sub If ra.Areas(1).Count <> ra.Areas(2).Count Then MsgBox msg2, vbCritical, "Ошибка": Exit Sub Application.ScreenUpdating = False arr2 = ra.Areas(2).Value ra.Areas(2).Value = ra.Areas(1).Value ra.Areas(1).Value = arr2 End Sub
Игорь, спасибо, это то что нужно. Только всё-таки просьба повестить код на ПКМ, а не на сочетание клавиш. Плюс работать это должно в любой книге...
Игорь, спасибо, это то что нужно. Только всё-таки просьба повестить код на ПКМ, а не на сочетание клавиш. Плюс работать это должно в любой книге...Serge_007
Это можно, но сложнее. Тогда весь код нужно поместить в модуль в Personal.xls или в другую книгу из автозагружаемых, плюс сделать исполнение при загрузке кода типа этого: [vba]
Код
Sub Inic() With Application.CommandBars("Cell").Controls.Add(Type:=msoControlButton, before:=1) .Caption = "SwapRanges" .OnAction = "SwapRanges" .FaceId = 203 End With End Sub
[/vba]
Т.е. при загрузке и выгрузки такие коды (обеспечение менюшки): [vba]
Код
Private Sub Workbook_BeforeClose(Cancel As Boolean) On Error Resume Next Application.CommandBars("Cell").Controls.Item("SwapRanges").Delete End Sub
Private Sub Workbook_Open() On Error Resume Next Application.CommandBars("Cell").Controls.Item("SwapRanges").Delete On Error GoTo 0 Inic End Sub
[/vba]
Можно вероятно эти коды совместить, но у меня так работает, правда задачу другую в итоге выполняет.
Цитата (Serge_007)
Плюс работать это должно в любой книге
Это можно, но сложнее. Тогда весь код нужно поместить в модуль в Personal.xls или в другую книгу из автозагружаемых, плюс сделать исполнение при загрузке кода типа этого: [vba]
Код
Sub Inic() With Application.CommandBars("Cell").Controls.Add(Type:=msoControlButton, before:=1) .Caption = "SwapRanges" .OnAction = "SwapRanges" .FaceId = 203 End With End Sub
[/vba]
Т.е. при загрузке и выгрузки такие коды (обеспечение менюшки): [vba]
Код
Private Sub Workbook_BeforeClose(Cancel As Boolean) On Error Resume Next Application.CommandBars("Cell").Controls.Item("SwapRanges").Delete End Sub
Private Sub Workbook_Open() On Error Resume Next Application.CommandBars("Cell").Controls.Item("SwapRanges").Delete On Error GoTo 0 Inic End Sub
[/vba]
Можно вероятно эти коды совместить, но у меня так работает, правда задачу другую в итоге выполняет.Hugo
Sub Selection_eXchange() '--------------------------------------------------------------------------------------- ' Procedure : Selection_eXchange ' Author : Alex_ST ' Topic_HEADER : Поменять указанные столбцы местами с помощью макроса ' Topic_URL : http://www.planetaexcel.ru/forum.php?thread_id=15210 ' Post_Author : Alex_ST ' Post_URL : http://www.planetaexcel.ru/forum.php?thread_id=15210 ' DateTime : 13.04.10, 16:33 ' Purpose : обменять ТЕКСТ двух выделенных диапазонов или областей ' Notes : '--------------------------------------------------------------------------------------- If Not TypeName(Selection) = "Range" Then Exit Sub Dim tmpVar1, tmpVar2 Dim tmpRng1 As Range, tmpRng2 As Range With Selection 'With Intersect(Selection, Selection.Parent.UsedRange) Select Case .Areas.Count Case 1 ' выделена 1 область If .Count = 2 Then ' выделено 2 ячейки Set tmpRng1 = .Cells(1): Set tmpRng2 = .Cells(2) ElseIf .Rows.Count = 2 And .Columns.Count > 2 Then ' выделен горизонтальный диапазон в 2 строки Set tmpRng1 = Range(Cells(.Row, .Column), Cells(.Row, .Column + .Columns.Count - 1)) ' 1-я строка диапазона Set tmpRng2 = tmpRng1.Offset(1, 0) ' 2-я строка ниже на 1 ElseIf .Columns.Count = 2 And .Rows.Count > 2 Then ' выделен вертикальный диапазон в 2 столбца Set tmpRng1 = Range(Cells(.Row, .Column), Cells(.Row + .Rows.Count - 1, .Column)) ' 1-й столбец Set tmpRng2 = tmpRng1.Offset(0, 1) ' 2-й столбец правее на 1 Else: Exit Sub End If Case 2 ' выделено 2 области If .Areas(1).Columns.Count = .Areas(2).Columns.Count And _ .Areas(1).Rows.Count = .Areas(2).Rows.Count Then ' одинаковая размерность областей Set tmpRng1 = .Areas(1): Set tmpRng2 = .Areas(2) End If Case Else: Exit Sub End Select End With Application.ScreenUpdating = False: Application.EnableEvents = False tmpVar1 = tmpRng1: tmpVar2 = tmpRng2 tmpRng1.Value = tmpVar2: tmpRng2.Value = tmpVar1 Application.EnableEvents = True: Application.ScreenUpdating = True End Sub
[/vba]
Я на Планете уже выкладывал такое решение: [vba]
Код
Sub Selection_eXchange() '--------------------------------------------------------------------------------------- ' Procedure : Selection_eXchange ' Author : Alex_ST ' Topic_HEADER : Поменять указанные столбцы местами с помощью макроса ' Topic_URL : http://www.planetaexcel.ru/forum.php?thread_id=15210 ' Post_Author : Alex_ST ' Post_URL : http://www.planetaexcel.ru/forum.php?thread_id=15210 ' DateTime : 13.04.10, 16:33 ' Purpose : обменять ТЕКСТ двух выделенных диапазонов или областей ' Notes : '--------------------------------------------------------------------------------------- If Not TypeName(Selection) = "Range" Then Exit Sub Dim tmpVar1, tmpVar2 Dim tmpRng1 As Range, tmpRng2 As Range With Selection 'With Intersect(Selection, Selection.Parent.UsedRange) Select Case .Areas.Count Case 1 ' выделена 1 область If .Count = 2 Then ' выделено 2 ячейки Set tmpRng1 = .Cells(1): Set tmpRng2 = .Cells(2) ElseIf .Rows.Count = 2 And .Columns.Count > 2 Then ' выделен горизонтальный диапазон в 2 строки Set tmpRng1 = Range(Cells(.Row, .Column), Cells(.Row, .Column + .Columns.Count - 1)) ' 1-я строка диапазона Set tmpRng2 = tmpRng1.Offset(1, 0) ' 2-я строка ниже на 1 ElseIf .Columns.Count = 2 And .Rows.Count > 2 Then ' выделен вертикальный диапазон в 2 столбца Set tmpRng1 = Range(Cells(.Row, .Column), Cells(.Row + .Rows.Count - 1, .Column)) ' 1-й столбец Set tmpRng2 = tmpRng1.Offset(0, 1) ' 2-й столбец правее на 1 Else: Exit Sub End If Case 2 ' выделено 2 области If .Areas(1).Columns.Count = .Areas(2).Columns.Count And _ .Areas(1).Rows.Count = .Areas(2).Rows.Count Then ' одинаковая размерность областей Set tmpRng1 = .Areas(1): Set tmpRng2 = .Areas(2) End If Case Else: Exit Sub End Select End With Application.ScreenUpdating = False: Application.EnableEvents = False tmpVar1 = tmpRng1: tmpVar2 = tmpRng2 tmpRng1.Value = tmpVar2: tmpRng2.Value = tmpVar1 Application.EnableEvents = True: Application.ScreenUpdating = True End Sub
============================================================== Стоит задача с помощью макроса в Exel поменять местами выделенные ячейки (ну или выделенные строки/столбцы), при этом ячейки(или строки/столбцы) не являются смежными, а - произвольно выбранными пользователем. EducatedFool VBA Developer --------------------------------------------------------------------------------
Вот вам макрос:
Код:
Sub SwapRanges() Dim ra As Range: Set ra = Selection msg1 = "Надо выделить ДВА диапазона ячеек одинакового размера" msg2 = "Надо выделить 2 диапазона ячеек ОДИНАКОВОГО размера" If ra.Areas.Count <> 2 Then MsgBox msg1, vbCritical, "Ошибка": Exit Sub If ra.Areas(1).Count <> ra.Areas(2).Count Then MsgBox msg2, vbCritical, "Ошибка": Exit Sub Application.ScreenUpdating = False arr2 = ra.Areas(2).Value ra.Areas(2).Value = ra.Areas(1).Value ra.Areas(1).Value = arr2 End Sub
============================================================== Стоит задача с помощью макроса в Exel поменять местами выделенные ячейки (ну или выделенные строки/столбцы), при этом ячейки(или строки/столбцы) не являются смежными, а - произвольно выбранными пользователем. EducatedFool VBA Developer --------------------------------------------------------------------------------
Вот вам макрос:
Код:
Sub SwapRanges() Dim ra As Range: Set ra = Selection msg1 = "Надо выделить ДВА диапазона ячеек одинакового размера" msg2 = "Надо выделить 2 диапазона ячеек ОДИНАКОВОГО размера" If ra.Areas.Count <> 2 Then MsgBox msg1, vbCritical, "Ошибка": Exit Sub If ra.Areas(1).Count <> ra.Areas(2).Count Then MsgBox msg2, vbCritical, "Ошибка": Exit Sub Application.ScreenUpdating = False arr2 = ra.Areas(2).Value ra.Areas(2).Value = ra.Areas(1).Value ra.Areas(1).Value = arr2 End Sub
slavaleks, в этом посте съехал текст кода. Вы подправили у себя? Если нет, подождите пока Игорь не исправит. Я ему в личку просьбу об этом кинул. Отображение кода Hugo починил.
slavaleks, в этом посте съехал текст кода. Вы подправили у себя? Если нет, подождите пока Игорь не исправит. Я ему в личку просьбу об этом кинул. Отображение кода Hugo починил.Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Четверг, 21.03.2013, 08:42
Ну, пока делать было нечего я сам поправил и чуть сократил то, что исказилось в посте Hugo. В модуле ЭтаКнига должно быть прописано так[vba]
Код
Private Sub Workbook_BeforeClose(Cancel As Boolean) On Error Resume Next Application.CommandBars("Cell").Controls.Item("SwapRanges").Delete End Sub
Private Sub Workbook_Open() On Error Resume Next With Application.CommandBars("Cell").Controls .Item("SwapRanges").Delete With .Add(Type:=msoControlButton, before:=1) .Caption = "SwapRanges" .OnAction = "SwapRanges" .FaceId = 203 End With End With On Error GoTo 0 End Sub
[/vba]
Ну, пока делать было нечего я сам поправил и чуть сократил то, что исказилось в посте Hugo. В модуле ЭтаКнига должно быть прописано так[vba]
Код
Private Sub Workbook_BeforeClose(Cancel As Boolean) On Error Resume Next Application.CommandBars("Cell").Controls.Item("SwapRanges").Delete End Sub
Private Sub Workbook_Open() On Error Resume Next With Application.CommandBars("Cell").Controls .Item("SwapRanges").Delete With .Add(Type:=msoControlButton, before:=1) .Caption = "SwapRanges" .OnAction = "SwapRanges" .FaceId = 203 End With End With On Error GoTo 0 End Sub
Alex_ST, Всё работает супер, за что, премного благодарен! Вот ещё дилетантский вопрос остался. Это нормально, что при выполнении любого макроса у меня не работает "Шаг назад" Ctrl+Z?
Alex_ST, Всё работает супер, за что, премного благодарен! Вот ещё дилетантский вопрос остался. Это нормально, что при выполнении любого макроса у меня не работает "Шаг назад" Ctrl+Z?slavaleks