замена символа * на значения соседнего столбца.

Программирование на Visual Basic for Applications
Boombeat
Начинающий
Начинающий
 
Сообщения: 23
Зарегистрирован: 15.01.2005 (Сб) 12:32

замена символа * на значения соседнего столбца.

Сообщение Boombeat » 08.08.2006 (Вт) 22:18

Есть задача - в таблице 15000 строк. Нужно чтобы в столбце 1 все значения равные * (имеется ввиду символ звездочка) менялись на значения столбца 2 (они числовые) умноженные на 5.
Пробовал перебором (For>Next) макрос наглухо зависает. Как можно решиь эту проблему чтобы это занимало как можно меньше времени

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 08.08.2006 (Вт) 22:22

Для начала нужно пояснить, где таблица.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 09.08.2006 (Ср) 1:35

Попробуй так:

Код: Выделить всё
Sub test1()
    Dim rng As Range, c As Range, col As String
    On Error GoTo ErrHandle
    col = "A"
    With ActiveSheet
        Set rng = .Range(.Cells(2, col), .Cells(.Rows.Count, col).End(xlUp)) _
            .SpecialCells(xlCellTypeConstants, xlTextValues)
    End With
    With Application
        .ScreenUpdating = False
        '.EnableEvents = False
        '.Calculation = xlCalculationManual
        For Each c In rng
            If c = "*" Then c = c.Offset(, 1) * 5
        Next c
        '.EnableEvents = True
        '.Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
    End With
ErrHandle:
End Sub
Привет,
KL

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 09.08.2006 (Ср) 1:35

или так:

Код: Выделить всё
Sub test2()
    Dim rng As Range, c As Range, col As String
    On Error GoTo ErrHandle
    col = "A"
    With ActiveSheet
        Set rng = .Range(.Cells(2, col), .Cells(.Rows.Count, col).End(xlUp)) _
            .SpecialCells(xlCellTypeConstants, xlTextValues)
    End With
    With Application
        .ScreenUpdating = False
        '.EnableEvents = False
        '.Calculation = xlCalculationManual
        For Each c In rng
            If InStr(c, "*") Then c = c.Offset(, 1) * 5
        Next c
        '.EnableEvents = True
        '.Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
    End With
ErrHandle:
End Sub
Привет,
KL

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 09.08.2006 (Ср) 1:39

если строк больше 16.384, то может возникнуть след. проблема:
http://support.microsoft.com/kb/832293/en Тогда так:

Код: Выделить всё
Sub test3()
    Dim rng As Range, c As Range, col As String, mtx
    On Error GoTo ErrHandle
    col = "A"
    With ActiveSheet
        Set rng = .Range(.Cells(2, col), .Cells(.Rows.Count, col).End(xlUp)).Resize(, 2)
    End With
    mtx = rng
    With Application
        .ScreenUpdating = False
        '.EnableEvents = False
        '.Calculation = xlCalculationManual
        For i = 1 To UBound(mtx, 1)
            If InStr(mtx(i, 1), "*") Then mtx(i, 1) = mtx(i, 2) * 5
        Next i
        rng = mtx
        '.EnableEvents = True
        '.Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
    End With
ErrHandle:
End Sub
Привет,
KL

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 09.08.2006 (Ср) 9:36

Если таки действительно имелся в виду Эксель, то быстрее, ИМХО, будет создать дополнительный столбец, в котором забить формулу типа "=ЕСЛИ(A1="*";B1*5;A1)", потом вставить его по значению на место столбца A.
Быть... или не быть. Вот. В чём вопрос?

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 09.08.2006 (Ср) 14:04

если операция разовая и осуществляется OP, а не др. юзером, тогда формулой пож. быстрее, а так нет.
Привет,
KL

uhm
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1597
Зарегистрирован: 02.12.2004 (Чт) 15:21

Сообщение uhm » 09.08.2006 (Ср) 16:51

Формулы тоже можно писать и растягивать из макроса. А перебор ячеек - это почти всегда дольше.
Быть... или не быть. Вот. В чём вопрос?

Boombeat
Начинающий
Начинающий
 
Сообщения: 23
Зарегистрирован: 15.01.2005 (Сб) 12:32

Сообщение Boombeat » 11.08.2006 (Пт) 14:55

lapink2000 писал(а):Попробуй так:

Код: Выделить всё
Sub test1()
    Dim rng As Range, c As Range, col As String
    On Error GoTo ErrHandle
    col = "A"
    With ActiveSheet
        Set rng = .Range(.Cells(2, col), .Cells(.Rows.Count, col).End(xlUp)) _
            .SpecialCells(xlCellTypeConstants, xlTextValues)
    End With
    With Application
        .ScreenUpdating = False
        '.EnableEvents = False
        '.Calculation = xlCalculationManual
        For Each c In rng
            If c = "*" Then c = c.Offset(, 1) * 5
        Next c
        '.EnableEvents = True
        '.Calculation = xlCalculationAutomatic
        .ScreenUpdating = True
    End With
ErrHandle:
End Sub



Спасибо за помощь. Все работает так как нужно!

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 12.08.2006 (Сб) 0:43

Привет uhm,
uhm писал(а):...перебор ячеек - это почти всегда дольше.

Хотя разница во времени и ничтожная (в 20.000 ячеек, где каждая вторая "*", на моей машине 0.546 сек против 0.25 сек), все таки согласен - красивее так:
Код: Выделить всё
    With rng
        .Offset(, 2) = "=IF(RC[-2]=""*"",RC[-1]*5,RC[-2])"
        .Value = .Offset(, 2).Value
        .Offset(, 2).ClearContents
    End With
Привет,
KL

KL
Microsoft MVP
 
Сообщения: 483
Зарегистрирован: 30.10.2005 (Вс) 0:31
Откуда: Madrid

Сообщение KL » 12.08.2006 (Сб) 0:44

Кстати, если ячеек с "*" не половина, а знач. меньше, то мой первый код будет быстрее подстановки формул ;-) но это частный случай
Привет,
KL


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, Yandex-бот и гости: 64

    TopList