Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Excel VBA (часть 3)

Автор: vlth
Дата сообщения: 14.03.2010 10:31
Swindler1

Код: Private Sub Worksheet_Change(ByVal Target As Range)
Dim lngEndRow As Long
With Me
lngEndRow = .Cells(.Rows.Count, 1).End(xlUp).Row
If lngEndRow > 501 Then
If Not IsEmpty(.Cells(501, 1)) And Not IsEmpty(.Cells(501, 9)) Then _
Range(.Cells(2, 1), .Cells(lngEndRow - 500, 9)).Delete Shift:=xlUp
End If
End With
End Sub
Автор: Valentino10
Дата сообщения: 14.03.2010 10:32
Доброго времени суток!
Мужики помогите, пожалуйста!

Задачку дали на работе, а решить не знаю как.

Задачка следующая:
Дано:
Таблица (выгрузка по городам):

Таблица Оч большая – Оч много строк.
Задача: Оч нужен скрипт, который бы искал по столбцу Город заданный город (например, Москва) и копировал всю соответствующую строку или на новый лист или в отдельную excel-таблицу. Желательно чтобы Шапка в новой excel-таблице, тоже была.

Добавлено:
Ссылка текст и картинки:

http://disk.tom.ru/szqh3q1
Автор: NJCorp
Дата сообщения: 14.03.2010 10:53
Valentino10
Автофильтр тебе не подойдет?
Автор: ZlydenGL
Дата сообщения: 14.03.2010 11:16
Valentino10, а задачу точно надо средствами Excel VBA решать? Ибо в Excel (до 2007) помещается только 65535 тысяч строк.
Автор: Swindler1
Дата сообщения: 14.03.2010 11:38

Цитата:
Swindler1
Думаю на словах ето примерно так...
если последняя строчка больше 501 тогда...
х = последняя.строка - 501
строки с 2 по х .удалить

сори, шас времени маловато код писать.


Спасибо Вам. Я алгоритмически представлял, что это должно быть как-то так.
А вот с реализацией у меня тоска, т.к. раньше в "услугах" Excel не нуждался, а теперь вопрос встал весьма остро.
Я уже читаю большую стопку макулатуры по VBA, но пока еще далеко до серьезных шагов. А в моем вопросе напартачить НЕЛЬЗЯ...
Если это не займет много времени, мож поможете...?
Автор: lvovichd
Дата сообщения: 14.03.2010 14:09
Здравствуйте!
Возникла проблема при переходе с Excel 2003 на Excel 2007:

Не работает запуск макроса(процедуры) открытой книги (формат - с поддержкой макросов) из макроса личной книги макросов.

В процедуре из PERSONAL.XLSB строка
...
Application.Run "work_file.xlsm!Raz1"
...
Даёт ошибку: "Не удаётся выполнить макрос... Возможно, этот макрос отсутствует в текущей книге, либо все макросы отключены"
В это время work_file.xlsm открыт, процедура Raz1 есть! В параметрах макросов включены "Включить все макросы" и "Доверять доступ к объектной модели..."
Автор: ZlydenGL
Дата сообщения: 14.03.2010 14:33
А через обычный Call запуск не проходит?
Автор: lvovichd
Дата сообщения: 14.03.2010 15:08
ZlydenGL
нет... не проходит...

Call Raz1

Выдаёт "Compile Error" - неопределена функция или процедура...

-----------------------
Наверное всё это можно обойти, вставив нужный мне кусок кода в процедуру личной книги макросов и переопределив объекты... но больно неохота - оставлю на крайний случай. Работало ведь...
Автор: Valentino10
Дата сообщения: 14.03.2010 17:15
NJCorp

К сожалению автофильтр не подойдет, по причине того, что в столбце Город города написаны по разному...например Москва_город, или Москва_область...и количество городов получается = количеству строк..

Добавлено:
ZlydenGL

Да, нужно сделать или на VBA или VBS, максимальное количество строк в выгрузке (таблице) около 1000 строк.

Любой способ, главное чтобы работало!
Автор: vlth
Дата сообщения: 14.03.2010 20:00
Valentino10, по описанию получается, что Вам нужно скопировать единственную строку на новый лист, да ещё и с шапкой. А смысл? - непонятно... Ещё более ставит в тупик наличие пяти строк ("Москва") на новом листе в образце. Где правда?
Потом, если могут быть названия типа "Москва_город" и "Москва_область", то как их различать? - так и будете вводить? Но в примере только "Москва", без "города"(???)

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



Добавлено:
Swindler1

Цитата:
Если это не займет много времени, мож поможете...?

Вас чем-то не устраивает мой ответ?
11:31 14-03-2010
Автор: Swindler1
Дата сообщения: 15.03.2010 05:18

Цитата:
Добавлено:
Swindler1

Цитата:Если это не займет много времени, мож поможете...?


Вас чем-то не устраивает мой ответ?
11:31 14-03-2010


Устраивает полностью! Пожалуй это ЛУЧШЕЕ решение моего вопроса!!!
Очевидный профессионализм!
Спасибо!!!
Автор: Valentino10
Дата сообщения: 15.03.2010 17:29
vlth

Да, к сожалению, я тут плохо описал. Постараюсь, объяснить более понятнее:
Есть ОЧ большая таблица (выгрузка) по всем городам, остастями и деревнями (Первый столбик - Город), и столбики со 2 по 11 (с соответствующими данными к городам). Строк с различными и одинаковыми городами порядка 2000. Необходимо сделать такой скрипт, в который бы я мог вписать город (например, Москва), и который бы искал в столбике Город именно Москву и выписывал всю соответствующую строку на новый лист. В результате обработки которого, на новом листе, отображалась бы информация с теми же столбцами, но только именно конкретного поискового города.

Единственной строки по 1 городу не будет, так как город Москва встречается во многих строках.

5 строк "Москва" - это пример...то есть, есть большая таблица, и из нее выделился именно конкретный кусок, по поисковому городу Москва.

Что касается того, что
"Потом, если могут быть названия типа "Москва_город" и "Москва_область", то как их различать? - так и будете вводить? Но в примере только "Москва", без "города"(???) "

Тут я этим хотел сказать, что скрипт должен искать только по городу. А ячейки в столбике Город могут быть как Москва, Москва_город, Москва_область.... Если это конечно возможно. Если нет, то тогда я сам буду добавлять и город, и город_город, и город_область...и так далее.

Прошу прощения, моё описание действительно плохое.
Автор: lvovichd
Дата сообщения: 15.03.2010 19:42
Разобрался со своей проблемой сам!
Всё дело оказалось в ИМЕНИ процедуры!!!
Я переименовал в Excel 2007 процедуру из "Raz1" в "RazOne" и всё ЗАРАБОТАЛО!

Всем удачи!
Автор: vlth
Дата сообщения: 15.03.2010 19:48

Цитата:
Я переименовал в Excel 2007 процедуру из "Raz1" в "RazOne" и всё ЗАРАБОТАЛО!

lvovichd, т.е. в 2007-м имена процедур не должны содержать цифр?



Добавлено:
Valentino10, есть ещё, по крайней мере один, вопрос: новый лист будет создаваться однократно? - будут ли в этом случае на него в дальнейшем заноситься данные?
Автор: Johnson Finger
Дата сообщения: 16.03.2010 10:08
Всем дорого дня, это опять я, со своими вредными вопросами
В общем есть интереся проблемка есть столбец, в котором забиты даты, но не в свсем правильном формате, во первых, они в екстовом формате, во вторых, выглядят примерно как 2001.12.31, т.е. год/месяц/день. Причем, когда я ставлю формат ячеек "Дата" по маске день/месяц/год, ничего не меняется. Пробовал асильно вбивать в ячейку с помощью макроса это значение, т.е. примерно как ActiveCell.Formula = Activecell.Value (с указанием формата даты раумеется), это все равно ничего не меняло. Только когда я учами захожу в каждую ячеку, т.е. в строку реактирования формулы, и просто нажимаю на Enter, ничего причем не меняя в ячейке, тольо тогда дата становится такой, какой я указал фрмат для нее. Собственно вопрос, как можно пофиксить это но с помощью VBA? Эмуляцию клавишь не предлагать, ибо это гемор и изврат.
Автор: ZlydenGL
Дата сообщения: 16.03.2010 10:15
Johnson Finger, есть два варианта:

1. В какой-то момент играть с региональными настройками (выставить формат даты гггг.мм.дд, обработать данные, а потом вернуть все "взад" для комфортной работы).
2. Создать второй столбец, в котором будет формула вида:

Код: =date(left(A1;4);mid(A1;5;2);right(A1;2))
Автор: vlth
Дата сообщения: 16.03.2010 11:50
Johnson Finger, у меня получилось "победить" Excel так:
Код: Dim x As Date, oCell As Range
With Selection
For Each oCell In .Cells
x = oCell: oCell = x
Next
End With
Автор: Swindler1
Дата сообщения: 16.03.2010 12:47

Цитата:
vlth
Добавлено:
Swindler1
Цитата:Если это не займет много времени, мож поможете...?

Вас чем-то не устраивает мой ответ?
11:31 14-03-2010


А все-таки - не устраивает!
Можно, пожалуйста, поподробнее: куда и как это правильно вставить, как запустить.
Опыт в работе с Excel, а тем более VBA - весьма и весьма слабый. Только приступил к интенсивному изучению...
Автор: vlth
Дата сообщения: 16.03.2010 18:06

Цитата:
Можно, пожалуйста, поподробнее: куда и как это правильно вставить, как запустить.

Вставить нужно в модуль листа, в котором должны отслеживаться изменения.
(В редакторе VB щёлкаем 2 раза по иконке листа (иконки видны в проводнике проектов, который вызывается клавишами ctrl + R), в открывшееся окно вставляем код)
Запускать ничего не надо: это процедура обработки события "изменение на листе", Excel будет сама запускать её при каждом изменении ячеек листа.
Подобное можно сделать для всех рабочих листов книги. Для этого нужно поместить код процедуры в модуль книги (модуль ЭтаКнига, процедура Workbook_SheetChange).
Автор: Valentino10
Дата сообщения: 16.03.2010 18:23
vlth

Да, новый лист будет создаваться однокраино.
Автор: Swindler1
Дата сообщения: 16.03.2010 20:56

Цитата:
vlth

Вставить нужно в модуль листа, в котором должны...



Низкий поклон!!!
Ковыряюсь...
Автор: vlth
Дата сообщения: 17.03.2010 01:20
Valentino10, вот Ваш модуль. Замените название "Лист2" на имя листа, с которого берёте данные. Из 2х процедур - prcCopyRange() и prcCopyRange2() - выберите ту, которая Вас больше устроит (prcCopyRange() добавляет данные на новый лист, prcCopyRange2() - заменяет данные "нового" листа)

Код: Option Explicit
Sub prcCopyRange()
Dim x As String, oRangeToCopy As Range, lngLastRow As Long
x = InputBox("Введите название населённого пункта", "Город, село, деревня...", "москва")
If Len(x) > 0 Then
x = fncMakeName(x)
Set oRangeToCopy = fncReturnRange(x)
If Not oRangeToCopy Is Nothing Then
With ThisWorkbook.Worksheets
If Not fncIsExistsWS(x) Then
.Add After:=.Item(.Count)
.Item(.Count).Name = x
Set oRangeToCopy = _
Union(Range(.Item("Лист2").Cells(1, 1), _
.Item("Лист2").Cells(1, 11)), oRangeToCopy)
End If
lngLastRow = .Item(x).Cells(.Item(x).Rows.Count, 1).End(xlUp)
oRangeToCopy.Copy .Item(x).Cells(lngLastRow + 1, 1)
End With
End If
End If
End Sub
Sub prcCopyRange2()
Dim x As String, oRangeToCopy As Range
x = InputBox("Введите название населённого пункта", "Город, село, деревня...", "москва")
If Len(x) > 0 Then
x = fncMakeName(x)
Set oRangeToCopy = fncReturnRange(x)
If Not oRangeToCopy Is Nothing Then
With ThisWorkbook.Worksheets
If Not fncIsExistsWS(x) Then
.Add After:=.Item(.Count)
.Item(.Count).Name = x
End If
Set oRangeToCopy = _
Union(Range(.Item("Лист2").Cells(1, 1), _
.Item("Лист2").Cells(1, 11)), oRangeToCopy)
.Item(x).Cells(1, 1).CurrentRegion.Clear
oRangeToCopy.Copy .Item(x).Cells(1, 1)
End With
End If
End If
End Sub
Function fncMakeName(strNameOfPoint As String) As String
Dim astrArray() As String, i As Byte, x As String
astrArray = Split(strNameOfPoint)
For i = 0 To UBound(astrArray)
x = Trim(astrArray(i))
astrArray(i) = UCase(Left(x, 1)) & LCase(Right(x, Len(x) - 1))
Next i
fncMakeName = Join(astrArray)
End Function
Function fncReturnRange(strSearch As String) As Range
Dim oCell As Range, oRange As Range, strFAddr As String

With ThisWorkbook.Worksheets("Лист2")
Set oCell = .Columns(1).Find(strSearch, LookIn:=xlValues, LookAt:=xlWhole)
If Not oCell Is Nothing Then
strFAddr = oCell.Address
Set oRange = Range(oCell, oCell.Offset(, 10))
Do
Set oCell = .Columns(1).FindNext(oCell)
If oCell.Address <> strFAddr Then
Set oRange = Union(oRange, Range(oCell, oCell.Offset(, 10)))
Else: Exit Do
End If
Loop Until oCell Is Nothing
End If
End With
Set fncReturnRange = oRange
End Function
Function fncIsExistsWS(strWSName As String) As Boolean
Dim WS As Worksheet
For Each WS In ThisWorkbook.Worksheets
If WS.Name = strWSName Then
fncIsExistsWS = True
Exit Function
End If
Next
End Function
Автор: vlth
Дата сообщения: 17.03.2010 13:38
Valentino10
Цитата:
NJCorp

К сожалению автофильтр не подойдет...

В коде формирования диапазона для копирования на новый лист можно было бы воспользоваться и фильтрами, конечно — авто- или расширенным. Скорее всего, это ускорило бы его выполнение. Но для данных количеством порядка 2-3 тыс. это, думаю, несущественно.
Автор: Maximus777
Дата сообщения: 17.03.2010 14:24
Пипл! Полная победа! Да ещё с бонусами. Нашёл *.ocx, в котором куча контролов, половина из которых поддерживает темы XP! Из того что мне нада, CheckBox, Button, ListView. Так что флексгрид нафиг не нужен стал. Если кому интересно, пишите.
Автор: NJCorp
Дата сообщения: 17.03.2010 15:15
интересно конечно, викладивай.
Автор: Maximus777
Дата сообщения: 18.03.2010 08:00
Ссылка 1
Ссылка 2
Регается как обычно, складываем в System32 и даём команду regsvr32 ***.ocx
Автор: aleksey0
Дата сообщения: 18.03.2010 15:41
есть книга 1 со значениями на 1 листе:

мише 50
васе 20
марине 40

книга 2 со значениями на 1 листе:

мише 20
васе 30
марине 50

ну и туча таких же
требуется сделать книгу, в которой будет сумма всех одноименных ячеек
то есть



мише 70
васе 50
марине 90


так как вб и вба я на дух не переношу, NEED HELP!)
Автор: ZlydenGL
Дата сообщения: 18.03.2010 15:43
aleksey0, даже VBA не нужен - копай в сторону SumIF() (может быть - со сводными таблицами, чтобы со всех листов книг собрать все имена).
Автор: aleksey0
Дата сообщения: 18.03.2010 16:03
эмм, а можно по-подробнее, я в vba полный 0
Автор: ZlydenGL
Дата сообщения: 18.03.2010 16:09
aleksey0, еще раз: VBA не нужен! Хватит имеющегося функционала MS Excel.

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127

Предыдущая тема: VS 2010


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.