#excel #vba
#excel #vba
Вопрос:
В Excel я пытаюсь получить макрос для перемещения чисел с помощью «-«.
У меня есть столбец E
со списком чисел
54525841-1
454152
1365466
1254566-1
1452577-1
Я хочу, чтобы макрос перемещал все числа с тире или дефисом в конце в столбец C.
Поэтому мне нужно E1
было бы переместить C1
54525841-1.
Ответ №1:
Вам нужно будет изменить «Sheet1» на имя листа, на котором находятся ваши данные.
Просматривается каждая ячейка (с данными) в столбце E и перемещает значение в столбец C, если оно содержит тире.
Sub MoveDashes()
Dim Sheet As Worksheet
Dim Index As Long
Set Sheet = ThisWorkbook.Worksheets("Sheet1")
For Index = 1 To Sheet.Cells(Application.Rows.Count, "E").End(xlUp).Row
If InStr(1, Sheet.Cells(Index, "E"), "-") > 0 Then
Sheet.Cells(Index, "C") = Sheet.Cells(Index, "E").Value
Sheet.Cells(Index, "E").Value = ""
End If
Next
End Sub
Комментарии:
1. Я использовал макрос, и ничего не произошло.
2. ваш рабочий лист называется «Лист1»? Если нет, вам необходимо соответствующим образом скорректировать код.
3. Нет необходимости ссылаться на лист, если макрос выполняется, в то время как рассматриваемый лист является активным. Цикл for each также будет более эффективным, чем цикл for.
Ответ №2:
Обязательно ли это должен быть макрос? Как насчет расширенного фильтра?
Ваши числа находятся в столбце E. Предположим, у них есть заголовок.
E1: Number
E2: 54525841-1
E3: 454152
E4: 1365466
E5: 1254566-1
E6: 1452577-1
В отдельной области вашего рабочего листа (скажем, столбец G) укажите следующие критерии:
G1: Number
G2: *-*
Ваши расширенные критерии фильтрации будут выглядеть следующим образом:
Все, что содержит «-«, будет скопировано в столбец C.
Ответ №3:
Я заставил его работать следующим образом:
Sub MoveDash()
x = Range("E" amp; Rows.Count).End(xlUp).Row
For Each Cell In Range("E2:E" amp; x)
If InStr(Cell, "-") <> 0 Then
Cell.Offset(, 1) = Cell
Cell.ClearContents
End If
Next Cell
end sub
Ответ №4:
Вы можете сделать это без VBA, но вот эффективный способ сделать это с помощью объекта dictionary .
Sub MoveNumbersWithDash()
Application.ScreenUpdating = False
Dim i As Long, lastRow As Long
Dim varray As Variant
Dim dict As Object
Set dict = CreateObject("scripting.dictionary")
lastRow = Range("E" amp; Rows.Count).End(xlUp).Row
varray = Range("E1:E" amp; lastRow).Value
For i = 1 To UBound(varray, 1)
If InStr(1, varray(i, 1), "-") <> 0 Then
dict.Add i, varray(i, 1)
End If
Next
Range("C1").Resize(dict.Count).Value = _
Application.WorksheetFunction.Transpose(dict.items)
Application.ScreenUpdating = True
End Sub
Как это работает:
Основная тема здесь — избегать вызовов Excel (например, для каждого цикла). Это сделает функцию быстрой (особенно если у вас десятки и тысячи строк) и более эффективной. Сначала я нахожу последнюю ячейку, используемую в E, затем сбрасываю всю строку в массив вариантов за один ход. Затем я перебираю каждый элемент, проверяя, содержит ли он «-«, если это так, я добавляю его в объект словаря. ТОЧКА: добавьте запись в качестве ЭЛЕМЕНТА, а не КЛЮЧА. Это гарантирует, что мы допускаем дубликаты. Переменная I будет уникальной для каждой записи, поэтому я использую ее в качестве ключа. Затем я просто сбрасываю весь массив ячеек с «-» в столбец C.
Почему словарь?Объект dictionary работает очень быстро и имеет 2 действительно отличные функции: .Keys и .Товары. Они вернут массив всех ключей или элементов в словаре, для которого вы можете использовать функцию транспонирования, чтобы выгрузить весь столбец значений в Excel за один шаг. Супер эффективно.