Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » VBS/WSH/JS - [решено] Выбор нескольких ячеек экселя с помощью переменной в макросе.

Ответить
Настройки темы
VBS/WSH/JS - [решено] Выбор нескольких ячеек экселя с помощью переменной в макросе.

Новый участник


Сообщения: 46
Благодарности: 2

Профиль | Отправить PM | Цитировать


Здравствуйте.

Есть рабочий скрипт.

Код: Выделить весь код
Sub Unmerge()
'
' Unmerge Macro
'
'

   Dim rowCount As Long

          For rowCount = 2 To 2200
          ActiveSheet.Range("A" & rowCount).Select
            With Selection
        .HorizontalAlignment = xlGeneral
        .VerticalAlignment = xlCenter
        .WrapText = True
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = True
    End With
              Selection.Unmerge
        Next rowCount
For rowCount = 2 To 2200
          ActiveSheet.Range("B" & rowCount).Select
            With Selection
        .HorizontalAlignment = xlGeneral
        .VerticalAlignment = xlCenter
        .WrapText = True
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = True
    End With
    Selection.Unmerge
    Next rowCount
    ActiveSheet.Range("$A$1:$B$2171").AutoFilter Field:=1, Criteria1:="="
    Rows("3:2171").Select
    Selection.Delete Shift:=xlUp
    ActiveSheet.Range("$A$1:$B$1086").AutoFilter Field:=1
    Range("D1").Select
    End Sub
Хотелось бы вместо двух проходов (сперва столбец А, потом столбец В) делать один.
К сожалению, не смог разобраться, как это прописать.
На
Код: Выделить весь код
 ActiveSheet.Range("A" & rowCount: "В" & rowCount).Select
и всяческие вариации на эту тему ругается компилятор.
Что я делаю не так?

Отправлено: 16:34, 28-08-2018

 

Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата subuday77:
Есть рабочий скрипт. »
Ужас-ужас-ужас. Надо раз и навсегда забыть про .Select() (потому обязательно корректировать код после макрорекордера).


Цитата subuday77:
Что я делаю не так? »
Вы делаете «не так» следующее:
  • не даёте описание задачи;
  • не даёте описание того, что делает (или что должен был бы делать) код;
  • не упаковываете в архив образец Рабочей книги, для которой предназначен выложенный код, и не прикладываете его к сообщению.

Я вот смотрю на код и думаю — что он, собственно, делает и зачем? Вам действительно нужно всё вот это:
Код: Выделить весь код
        With Selection
            .HorizontalAlignment = xlGeneral
            .VerticalAlignment = xlCenter
            .WrapText = True
            .Orientation = 0
            .AddIndent = False
            .IndentLevel = 0
            .ShrinkToFit = False
            .ReadingOrder = xlContext
            .MergeCells = True
        End With
        
        Selection.Unmerge
или это — как было в макрорекордере записано, так и осталось?! Зачем нужно сначала .MergeCells = True и тут же — .Unmerge()?! Не нравится мне и жёстко привязанная адресация вида .Range("$A$1:$B$2171"), .Range("$A$1:$B$1086"). Впрочем, дело Ваше.

Убрал ненужный .Select(), остальное оставил как было.
Код: Выделить весь код
Option Explicit

Sub Unmerge()
    Dim iRowCount As Long
    Dim iColumnCount As Long
    
    For iColumnCount = 1 To 2
        For iRowCount = 2 To 2200
            With ActiveSheet.Cells.Cells(iRowCount, iColumnCount)
                .HorizontalAlignment = xlGeneral
                .VerticalAlignment = xlCenter
                .WrapText = True
                .Orientation = 0
                .AddIndent = False
                .IndentLevel = 0
                .ShrinkToFit = False
                .ReadingOrder = xlContext
                .MergeCells = True
                
                .Unmerge
            End With
        Next iRowCount
    Next iColumnCount
    
    ActiveSheet.Range("$A$1:$B$2171").AutoFilter Field:=1, Criteria1:="="
    Rows("3:2171").Select
    Selection.Delete Shift:=xlUp
    ActiveSheet.Range("$A$1:$B$1086").AutoFilter Field:=1
    Range("D1").Select
End Sub
Это сообщение посчитали полезным следующие участники:

Отправлено: 17:48, 28-08-2018 | #2



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

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


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


subuday77, я серьёзно спрашиваю по поводу:
Цитата Iska:
что он, собственно, делает и зачем? Вам действительно нужно всё вот это: »
ибо, если окажется, что Вам действительно нужно только рассплитить ячейки, то всё укладывается в одну строку:
Код: Выделить весь код
    With ActiveSheet
        .Range(.Cells.Cells(2, 1), .Cells.Cells(2200, 2)).Unmerge
    End With
вместо перебора кучи ячеек диапазона по одной.
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:32, 28-08-2018 | #3


Новый участник


Сообщения: 46
Благодарности: 2

Профиль | Отправить PM | Цитировать


Спасибо.
Про Select() я в курсе. Но грешен. Я ещё и <шопотом, оглядываясь> goto в батниках использую.
Но в целом, да, как записал, так и работает. Ну, почти. В напрямую записанном виде он не работал, по причине превышения 64 битного размера.
Пришлось слегка допилить.
Ваш способ очень хорош, более того, позволяет более гибко обработать лист.
Но в нём всё равно 2 прохода по листу.

И всё таки, можно как-то скомбинировать буквы и переменные?
Допустим, даже без Select.
Код: Выделить весь код
 For iRowCount = 2 To 2200
            With ActiveSheet.Cells.Cells("A" & iRowCount : "B" & iRowCount)
           .MergeCells = false
 End With
        Next iRowCount
Вот такое что-нибудь?

Цитата:
With ActiveSheet
.Range(.Cells.Cells(2, 1), .Cells.Cells(2200, 2)).Unmerge
End With
А что так можно было?!

А он не угробит содержимое всех ячеек, кроме верхней?
UPD. Проверил. Нет, не угробит.

Последний раз редактировалось subuday77, 28-08-2018 в 19:06.


Отправлено: 18:39, 28-08-2018 | #4


Новый участник


Сообщения: 46
Благодарности: 2

Профиль | Отправить PM | Цитировать


Изображения
Тип файла: png Image 3.png
(3.6 Kb, 4 просмотров)

Цитата Iska:
что он, собственно, делает и зачем? »
Расскажу.
Некое существо, ещё более криворукое, чем я, собрало кучу эксель листов копипастом с сайта.
Всё ничего, но данные выглядят так:
http://forum.oszone.net/attachment.p...1&d=1535471448
Их очень много.
И чтобы привести всё это в божеский вид, пришлось срочно осваивать VBS.
Часа за два сваял что-то, что разцепляет ячейки, не удаляя при этом содержимое, а потом сносит пустые строки.
Как-то так.

Отправлено: 18:54, 28-08-2018 | #5


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата subuday77:
Я ещё и <шопотом, оглядываясь> goto в батниках использую. »
Ну, тут, как бы, никуда не деться.


Цитата subuday77:
И всё таки, можно как-то скомбинировать буквы и переменные? »
Комбинировать можно, только не буквы, а диапазоны (например, по объединять по Union() (Application.Union Method (Excel) | Microsoft Docs) или брать пересечение по .Intersect() (Application.Intersect Method (Excel) | Microsoft Docs)). Но мы можеи просто взять диапазон зараз:
Код: Выделить весь код
    With ActiveSheet
        .Range(.Cells.Cells(2, 1), .Cells.Cells(2200, 2)).Unmerge
    End With
указывая в методе .Range() левую верхнюю ячейку и правую нижнюю ячейку диапазона. Причём, поскольку в методе .Range() требуется указание объектов типа Range, мы можем вместо метода .Cells() и цифр строки и столбца использовать буквенно-цифоровую адресацию, например:
Код: Выделить весь код
    With ActiveSheet
        .Range(.Range("A2"), .Range("B2200")).Unmerge
    End With
Цитата subuday77:
А что так можно было?! »
Конечно. Я потому и пишу, что обычно требуется сделать:
Скрытый текст
Цитата Iska:
Вы делаете «не так» следующее:
  • не даёте описание задачи;
  • не даёте описание того, что делает (или что должен был бы делать) код;
  • не упаковываете в архив образец Рабочей книги, для которой предназначен выложенный код, и не прикладываете его к сообщению.
»
потому как задача может быть решена совсем другим способом, может не нуждаться в выбранном решении и т.п.

Цитата subuday77:
А он не угробит содержимое всех ячеек, кроме верхней? »
А как? Это при объединении теряются значения всех объединённых ячеек, кроме самой верхней левой, но мы же тут разъединяем их, а не объединяем.

Цитата subuday77:
Расскажу.
Некое существо, ещё более криворукое, чем я, собрало кучу эксель листов копипастом с сайта.
Всё ничего, но данные выглядят так:
http://forum.oszone.net/attachment.p...1&d=1535471448
Их очень много.
И чтобы привести всё это в божеский вид, пришлось срочно осваивать VBS.
Часа за два сваял что-то, что разцепляет ячейки, не удаляя при этом содержимое, а потом сносит пустые строки.
Как-то так. »
subuday77, спасибо, ясно. Ну, тогда, значится, для однократного применения и Ваш код более чем гож, даже с прямым указанием адресации (разве что отрабатывать будет достаточно долго).
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:59, 28-08-2018 | #6


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


Цитата subuday77:
а потом сносит пустые строки. »
То есть, вот этот код у Вас:
Цитата subuday77:
Код: Выделить весь код
    ActiveSheet.Range("$A$1:$B$2171").AutoFilter Field:=1, Criteria1:="="
    Rows("3:2171").Select
    Selection.Delete Shift:=xlUp
    ActiveSheet.Range("$A$1:$B$1086").AutoFilter Field:=1
    Range("D1").Select
»
предназначен для удаления пустых строк?

Отправлено: 09:13, 29-08-2018 | #7


Новый участник


Сообщения: 46
Благодарности: 2

Профиль | Отправить PM | Цитировать


Вот, привёл вот к такому виду:
Код: Выделить весь код
Sub Unmerge()
'
' Unmerge Macro
'
'

  With ActiveSheet
    .Range("$A$2:$B$2200").Unmerge
    .Range("$A:$B").AutoFilter Field:=1, Criteria1:="="
     Rows("2:2200").Select
     Selection.Delete Shift:=xlUp
    .Range("$A:$B").AutoFilter Field:=1
    .Range("D1").Select
  End With
End Sub
Всё работает.
Ещё раз спасибо!

Отправлено: 09:24, 29-08-2018 | #8


Ветеран


Сообщения: 27449
Благодарности: 8086

Профиль | Отправить PM | Цитировать


subuday77, удалить можно ещё так:
Код: Выделить весь код
    Dim objRange As Variant
    …
    
    For Each objRange In ActiveSheet.Range("A2:A2200").SpecialCells(xlCellTypeBlanks).EntireRow.Areas
        objRange.Delete
    Next objRange
Берём в диапазоне .Range("A2:A2200") все пустые ячейки, берём целые строки от них, перебираем и удаляем каждую из отдельных областей полученного диапазона.

Почему именно .Range("A2:A2200"), а не .Range("A2:B2200")? Потому что Вы фильтруете по Field == 1.
Это сообщение посчитали полезным следующие участники:

Отправлено: 10:39, 29-08-2018 | #9



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » VBS/WSH/JS - [решено] Выбор нескольких ячеек экселя с помощью переменной в макросе.

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
2013 - поиск нескольких ячеек Alexander_88 Microsoft Office (Word, Excel, Outlook и т.д.) 2 05-10-2015 20:53
2003/XP/2000 - Как изменить белый (проз.) цвет в настройках MS Excel при выделении нескольких ячеек? naplon Microsoft Office (Word, Excel, Outlook и т.д.) 1 27-03-2012 18:21
Загрузка - Как урать выбор из нескольких ОС? Oleg1975 Microsoft Windows 2000/XP 7 11-08-2011 15:33
[решено]Получение переменной с HTML с помощью StringRegExpReplace ikif AutoIt 8 22-07-2009 10:15
Загрузка - Как с помощью Boot.ini и Total Comander расставить приоритеты среди нескольких О.С. ? Rik. Microsoft Windows 2000/XP 1 15-06-2008 14:06




 
Переход