VBA+Excel: помогите плз чайнику...

Программирование на Visual Basic for Applications
Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

VBA+Excel: помогите плз чайнику...

Сообщение Ztrel0cK » 25.03.2005 (Пт) 13:33

Встречался до этого с VBA только совсем малость и в аксессе...
Сейчас нужна помощь в следующем вопросе:
Имеем таблицу в экселе (это к сожалению принципиально, я отчетливо осознаю что задачу можно легко решить программными средствами аксесса).
Есть множество полей, но нас интересует только 2 из них.
Пусть это будет A:A - ФИО и B:B с вариантами пустое/YES/NO/HOLD (вводится ручками).

Задача: Если в поле B ставится значение YES, информация из поля А должна копироваться во второй лист (ессно добавлять последней, не замещая уже имеющуюся запись).

Буду весьма признателен за кусок кода, советы, рекомендации и вообще любую помощь =)

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 25.03.2005 (Пт) 17:50

:roll: Не подходит =)
что-бы остальные по линкам не бегали:
На самом деле, поясню еще один момент в задаче:
скорее это должна быть кнопка, или, что лучше, скрипт на заполнение поля B. Т.е. всю таблицу парсить не нужно, нужно реагировать на введение/изменение значения в поле B.

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

Сообщение GSerg » 25.03.2005 (Пт) 18:01

Так я и подумал в начале :)

Код: Выделить всё
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  If Target.Column = 2 Then
    If Target.Cells.Count = 1 Then
      If Target.Value = "YES" Then
        With ThisWorkbook.Worksheets("Скопированное")
          Target.Offset(0, -1).Copy .Cells(.UsedRange.Rows.Count + 1, 1)
        End With
      End If
    End If
  End If
End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 25.03.2005 (Пт) 18:44

Спасибо, похоже на правду, НО копирует бяка такая только в A2, те не проверяет куда кидать...

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

Сообщение GSerg » 26.03.2005 (Сб) 15:25

Гы. А он-таки может начинаться не с первой строки :) Жалко :)

Target - это столбец B, поэтому Target(1, 0) не есть хорошо. :)
Код: Выделить всё
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  If Target.Column = 2 Then
    If Target.Cells.Count = 1 Then
      If Target.Value = "YES" Then
        With ThisWorkbook.Worksheets("Скопированное")
          Target.Offset(0, -1).Copy .Cells(.Cells.SpecialCells(xlCellTypeLastCell).Row + 1, 1)
        End With
      End If
    End If
  End If
End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 26.03.2005 (Сб) 16:56

Спасибо огромное, почти идеально работает.
Возникли следующий вопрос:
скопировал вот он на второй лист. я последнюю запись удаляю (полностью всю строку). Следующее копирование произойдет не на то место, которое удалил, а на строку ниже, т.е. получаем пустую ячейку. Как этого избежать?
ЗЫ:
пока разбираюсь в переменных... подскажите плз. если мне нужно скопировать одновременно и соотвествующую ячейку столбца С, какие нужно внести изменения. Шаманство пока результата не принесло =(

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 26.03.2005 (Сб) 18:45

Большую часть дошаманил.
Осталось разобраться только с тем, чтобы корректно определялась пустая строка.

ЗЫ: Спасибо всем участникам, сильно жизнь облегчаете :!:

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

Сообщение GSerg » 27.03.2005 (Вс) 13:05

В том и фишка, что пустая строка, поскольку была раньше полной, то таковой и останется до сохранения и повторной загрузки :)
Посему...

Код: Выделить всё
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  If Target.Column = 2 Then
    If Target.Cells.Count = 1 Then
      If Target.Value = "YES" Then
        With ThisWorkbook.Worksheets("Скопированное")
          If IsEmpty(.Cells(1, 1).Value) Then
            Target.Offset(0, -1).Copy .Cells(1, 1)
          Else
            Target.Offset(0, -1).Copy .Cells(1, 1).Offset(.Cells(1, 1).CurrentRegion.Rows.Count)
          End If
        End With
      End If
    End If
  End If
End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 28.03.2005 (Пн) 8:32

Не могу понять, почему оно ругается на:
If IsEmpty(.Cells(0, 2).Value) Then
и вообще на все, где указано Cells(0,2)
Хотя
Row + 0, 2
работало превосходно...

Имею:
Код: Выделить всё
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  If Target.Column = 11 Then
    If Target.Cells.Count = 1 Then
      If Target.Value = "YES" Then
        With ThisWorkbook.Worksheets("AABS manager's interview")
        If IsEmpty(.Cells(1, 1).Value) And IsEmpty(.Cells(1, 2).Value) Then
            Target.Offset(0, -10).Copy .Cells(1, 1)
            Target.Offset(0, -1).Copy .Cells(1, 2)
          Else
            Target.Offset(0, -10).Copy .Cells(1, 1).Offset(.Cells(1, 1).CurrentRegion.Rows.Count)
            Target.Offset(0, -1).Copy .Cells(1, 2).Offset(.Cells(1, 2).CurrentRegion.Rows.Count)
          End If
        End With
     
      End If
    End If
  End If
End Sub


Таким образом получаю, что 2е копирование происходит на строку ниже...

Пытаюсь изменить на
Код: Выделить всё
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
  If Target.Column = 11 Then
    If Target.Cells.Count = 1 Then
      If Target.Value = "YES" Then
        With ThisWorkbook.Worksheets("AABS manager's interview")
        If IsEmpty(.Cells(1, 1).Value) And IsEmpty(.Cells(0, 2).Value) Then
            Target.Offset(0, -10).Copy .Cells(1, 1)
            Target.Offset(0, -1).Copy .Cells(0, 2)
          Else
            Target.Offset(0, -10).Copy .Cells(1, 1).Offset(.Cells(1, 1).CurrentRegion.Rows.Count)
            Target.Offset(0, -1).Copy .Cells(0, 2).Offset(.Cells(0, 2).CurrentRegion.Rows.Count)
          End If
        End With
     
      End If
    End If
  End If
End Sub

Что выглядит более логичным - оно начинает дико ругаться... Как решить данную проблемку? =)
Последний раз редактировалось Ztrel0cK 28.03.2005 (Пн) 8:38, всего редактировалось 1 раз.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 28.03.2005 (Пн) 8:37

Потому что нумерация начинается с 1, а не с 0.
Lasciate ogni speranza, voi ch'entrate.

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 28.03.2005 (Пн) 8:40

угму... А каким образом мне тогда скопировать не всю строку но отдельные ячейки, используя указанную выше проверку?

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

Сообщение GSerg » 28.03.2005 (Пн) 9:34

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

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 28.03.2005 (Пн) 9:38

разорванные.
Конкретизирую к примеру выше:
поле YES заполняется в K. Скопировать нужно ячейку A и J в A и C другого листа соответственно.

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

Сообщение GSerg » 28.03.2005 (Пн) 10:20

Код: Выделить всё
If IsEmpty(.Cells(1, 1).Value) Then
  Target.EntireRow.Cells(1).Copy .Cells(1, 1)
  Target.EntireRow.Cells(10).Copy .Cells(1, 3)
Else
  with .Cells(1, 1).Offset(.Cells(1, 1).CurrentRegion.Rows.Count).EntireRow
    Target.EntireRow.Cells(1).Copy .Cells(1,1)
    Target.EntireRow.Cells(10).Copy .Cells(1,3)
  end with
End If


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

Ztrel0cK
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 25.03.2005 (Пт) 12:46

Сообщение Ztrel0cK » 28.03.2005 (Пн) 10:28

Однако работает =)
Спасибо огромное!
Теперь начинаю задумываться, как сделать так, чтобы если с 1го листа запись удаляется, а во втором есть аналогичная - удалить ее из 2го =)

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

Сообщение GSerg » 28.03.2005 (Пн) 14:53

pashulka писал(а):Оставим на Вашей совести высказывание, что Target - это столбец "B"...
накладывает на Вас определённые обязательства ... в том числе и на формулировки.


Ну да, имелась в виду именно текущая ячейка столбца B, а не весь столбец B - впрочем, мне потребовалось некоторое время, чтобы понять, что моя формулировка не является совершенно точной :) Хотя, надо заметить, это нисколько не отразилось на полезности дальнейших изысканий :)

pashulka писал(а):А хотелось бы услышать, чем именно Вас не устраивает синтаксис : Target.Item(1, 0)

Если честно - фиг его знает :) Просто я никогда его не юзал, и, присмотревшись, понял, что никогда и не буду юзать :)
Эта проперть (о существовании которой я даже не подозревал) вносит некоторую путаницу :) Потому что во всех остальных пропертях исчисление идёт относительно родительского объекта. То есть, если родительский объект - ячейка B5, то мы не можем написать B5.Cells(1,2), к примеру, потому что такая ячейка не входит в родительский диапазон. И это позволяет делать условную, а не абсолютную, адресацию. И ещё позволяет вылавливать ошибки адресации. Ну не нравится мне категорически синтаксис, при котором параметрическая проперть объекта возвращает Range, выходящий за границы родительского. Это плохо и неправильно, на мой взгляд :) И мне потребовалось ещё некоторое время, чтобы понять, что это так строка возвращается, через (1, 0). Ну вот не нравится мне это :) EntireRow гораздо понятнее :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

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

Сообщение GSerg » 28.03.2005 (Пн) 15:59

Эээ.... чуть меньше официальности, плз :) Мы вроде тут как все на "ты", по причине того, что это не обижает, а объединяет :) Впрочем, уважаем иное мнение по этому поводу :)

несколько слукавили

Сказав, что она действительно неточна? :) Но она и правда не точна, что же тут лукавить :)

Касаемо второй части высказывания: оно сделано после того, как я проверил и получил Application or object defined error при попытке обратиться к ячейкам, выходящим за пределы родителя. Сейчас, кстати, работает :? Надо будет покопать :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в VBA

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

Сейчас этот форум просматривают: Mail.ru [бот] и гости: 31

    TopList