![]() |
|
| Правила Форума редакция от 22.06.2020 |
|
|||||||
|
|
Окажите посильную поддержку, мы очень надеемся на вас. Реквизиты для переводов ниже. |
|
![]() |
|
|
Опции темы | Опции просмотра |
Language
|
|
|
#1
|
|
Guest
Сообщений: n/a
|
В этой теме размещаем вопросы и ответы, а также советы и рекомендации по решению конкретных задач, которые требуют создания формулы, применения макроса, написания кода VBA, т.е. Практикум.
------------------------------ Вопросы и ответы, а также советы и рекомендации по настройке MS Excel, ошибки в работе программы, решение задач по импорту/экспорту документов, ссылки и обсуждение надстроек для Excel, обучающие материалы и т.п. размещаем в теме MS Excel - настройка, импорт/экспорт.Если решение задачи не требует применения формул и макросов (VBA), то это обсуждение будет перенесено в тему по настройкам. Все пожелания по принципам размещения сообщений по этим темам рассматриваются - пишите в личку Andrey_k. Последний раз редактировалось regist; 30.11.2012 в 15:04.. Причина: закрепил шапку |
|
|
|
#421
|
|
Неактивный пользователь
Пол:
Регистрация: 23.12.2009
Сообщений: 54
Репутация: 38
|
Висит потому, что выделяете весь столбец. А столбец-то небось в 2007 Excel, а это 1048576 строк. Делайте так:
Код:
Sub Test()
If TypeName(Selection) <> "Range" Then MsgBox "Выделенная область не является диапазоном!", vbCritical, "Ошибка": Exit Sub
Dim rCell As Range, rRange as range, a As Integer
Application.ScreenUpdating = False
set rRange = Intersect(Selection, ActiveSheet.Usedrange)
For Each rCell In rRange
a = InStr(rCell, " ")
If a < 6 Then
rCell = Mid(rCell, a + 1)
End If
Next rCell
Application.ScreenUpdating = True
End Sub
|
|
|
|
| Реклама: | Кольцо из желтого золота с лунным камнем и бриллиантами | Термостат накладной RAK-TW. 1200B-H | дома барнхаус с террасой | вк на ттк | речной круиз москва казань |
|
|
#422
|
|||||||||||||||||||
|
собственно сделал табличку, вроде пашет - но на будущее хотел узнать может можно проще?
пример
__________________
Век живи, Век - учись Последний раз редактировалось konstruktor; 16.07.2010 в 09:25.. |
||||||||||||||||||||
|
|
|
|
|
#423
|
|||||||||||||||||||||||
|
Неактивный пользователь
Пол:
Регистрация: 16.09.2008
Сообщений: 28
Репутация: 8
|
Макрос останавливается только после нажатия "Esc"/ Добавлено через 10 минут
Снова ругается: [IMG] |
|||||||||||||||||||||||
|
|
|
|
|
#424
|
|
Новичок
![]() Пол:
Регистрация: 16.07.2010
Сообщений: 19
Репутация: 1
|
Попробуй функцию "сцепить" посмотреть.
|
|
|
|
|
|
#425
|
|||||||||||||||||||||||
|
Неактивный пользователь
Пол:
Регистрация: 23.12.2009
Сообщений: 54
Репутация: 38
|
Это странно. Ругаться может по одной причине - Вы выделяете диапазон, в котором нет данных: Вот с проверкой - если диапазон является нулевых - выход из процедуры: Код:
Sub Test()
If TypeName(Selection) <> "Range" Then MsgBox "Выделенная область не является диапазоном!", vbCritical, "Ошибка": Exit Sub
Dim rCell As Range, rRange As Range, a As Integer
Set rRange = Intersect(Selection, ActiveSheet.UsedRange)
If rRange Is Nothing Then Exit Sub
Application.ScreenUpdating = False
For Each rCell In rRange
a = InStr(rCell, " ")
If a < 6 Then
rCell = Mid(rCell, a + 1)
End If
Next rCell
Application.ScreenUpdating = True
End Sub
|
|||||||||||||||||||||||
|
|
|
|
|
#426
|
||||||||||||||||||||||||||||||||||||||||||
|
Постоялец
![]() ![]() ![]() Пол:
Регистрация: 22.11.2006
Сообщений: 328
Репутация: 108
|
Пример, предложенный The_Prist пытается обработать всю область, заключенную между ячейками, содержащими данные. Например, если в ячейке A1 будет какое-то значение и в ячейке A500 будет значение, то обрабатываться будут все 500 ячеек, несмотря на то, что 498 из них пустые. Поэтому такой подход неоптимален по скорости. Лучше использовать: Selection.SpecialCells(xlCellTypeConstants). В этом случае будут обрабатываться только те ячейки из выделенного диапазона, которые содержат данные. Причем не просто данные, а константы. То есть формулы и пустые ячейки обрабатываться не будут. Таким образом, в нашей ситуации с A1-A100 обработаны будут только две ячейки. Кроме того, в исходном алгоритме есть ошибка вот в этой строке: a = InStr(rCell, " ") По условию сказано, что удалить нужно все первые слова строк, содержащие меньше 6 символов. В этом месте ищется первый пробел в строке. С помощью него определятся первое слово. НО если строка состоит из одного слова, состоящего, скажем из 3 символов и не содержит пробелов, то результатом функции InStr будет 0 и слово удалено не будет. Для исключения этой ситуации надо просто дописать в конце строки пробел. В этом случае функция гарантированно будет возвращать правильный результат: a = InStr(rCell + " ", " "). Но среди значений в ячейках могут быть как строки, так и числа. Поэтому перед обработкой строки фeнкцией InStr, надо убедиться, что аргумент, который ей передается - это строка. Для этого используем CStr(). Эта функция числовой аргумент преобразует в строку, а строковый оставит без изменений. И еще один момент. По условию задачи сказано, что должны удаляться слова, длиной меньше 6 символов. Тогда условие проверки должно быть записано так: If a < 7 Then rCell.Value = Mid(t, a + 1) а не так: If a < 6 Then rCell.Value = Mid(t, a + 1) потому, что найденная с помощью InStr позиция - это позиция пробела, а не последнего символа первого слова. В итоге имеем:
|
||||||||||||||||||||||||||||||||||||||||||
|
|
|
| Сказали спасибо: |
|
|
#427
|
|||||||||||||||||||||||
|
Неактивный пользователь
Пол:
Регистрация: 23.12.2009
Сообщений: 54
Репутация: 38
|
Согласен, но добавлю пару ложек дегтя. Выделите всего одну ячейку на листе с данными и запустите макрос. Результат будет радостный - обработаны будут все ячейки с константами на листе. Выделите диапазон, состоящий лишь из формул - ошибка. Т.е. надо проверять и на кол-во выделенных ячеек и на наличие констант. Т.е. получиться так: Код:
Sub Test()
Dim rCell As Range, rRange As Range, a As Integer, t As String
Application.ScreenUpdating = False
If Selection.Count = 1 Then
If ActiveCell.HasFormula = False Then
If Len(ActiveCell.Text) > 0 Then Set rRange = ActiveCell
End If
Else
On Error Resume Next
rRange = Selection.SpecialCells(xlCellTypeConstants)
End If
If rRange Is Nothing Then Exit Sub
On Error GoTo 0
For Each rCell In rRange
t = CStr(rCell.Text) & " "
a = InStr(t, " ")
If a < 7 Then rCell.Value = Mid(t, a + 1)
Next
Application.ScreenUpdating = True
End Sub
|
|||||||||||||||||||||||
|
|
|
| Сказали спасибо: |
|
|
#428
|
||||||||||||||||||||||||||||||||||||||||||
|
Постоялец
![]() ![]() ![]() Пол:
Регистрация: 22.11.2006
Сообщений: 328
Репутация: 108
|
Верно, это я не учел. Тогда для красоты еще чуть-чуть причешем:Код:
Sub Test() Dim rCell As Range, rRange As Range, a As Integer, t As String Application.ScreenUpdating = False Set rRange = Nothing On Error Resume Next If Selection.Count > 1 Then Set rRange = Selection.SpecialCells(xlCellTypeConstants) Else If Not (ActiveCell.HasFormula Or ActiveCell = Empty) Then Set rRange = ActiveCell End If If rRange Is Nothing Then Exit Sub For Each rCell In rRange t = CStr(rCell.Value) + " " a = InStr(t, " ") If a < 7 Then rCell.Value = Mid(t, a + 1) Next Application.ScreenUpdating = True End Sub
Согласен. ![]() Последний раз редактировалось DmitriC; 16.07.2010 в 10:16.. |
||||||||||||||||||||||||||||||||||||||||||
|
|
|
| Сказали спасибо: |
|
|
#429
|
|||||||||||||||||||||||
|
Пользователь
Пол:
Регистрация: 09.03.2006
Сообщений: 76
Репутация: 89
|
Какой объем обработки? Попробуйте, плз, еще раз. Со счетчиком, который будет показывать - какая ячейка по счету обрабатывается, - что макрос не завис. Так же добавил обработку пустых ячеек. Скорость возросла в два раза (но на пустом диапазоне в три столбца - при заполненом диапазоне скорость возрастет меньше) Код:
Sub Test()
Dim nCell As Double ' счетчик обрабатываемых ячеек, если ячеек будет много смените тип
If TypeName(Selection) <> "Range" Then MsgBox "Выделенная область не является диапазоном!", vbCritical, "Ошибка": Exit Sub
Dim rCell As Range, a As Integer
Application.ScreenUpdating = False
Selection.Activate
nCell = 0
For Each rCell In Selection
Application.StatusBar = "Обрабатываю " & nCell 'Сообщение в статусной строке
If a = 0 Then
a = InStr(rCell, " ")
If a < 6 Then
rCell = Mid(rCell, a + 1)
End If
End If
nCell = nCell + 1
Next rCell
Application.ScreenUpdating = True
'Application.StatusBar = False 'После отладки раскоментировать
End Sub
![]() Последний раз редактировалось MuhaZ; 16.07.2010 в 11:26.. |
|||||||||||||||||||||||
|
|
|
| Сказали спасибо: |
|
|
#430
|
|
Постоялец
![]() ![]() ![]() Пол:
Регистрация: 22.11.2006
Сообщений: 328
Репутация: 108
|
|
|
|
|
| Сказали спасибо: |
|
|
#431
|
|
мне не нравится, что я день убил чтоб его сделать
![]() наверняка можно проще (желательно без макросов) 1. выбрал изделие из списка (у меня список разбит по 20 изделий в группе) - это минус.. ограничение (хотелось бы больше, но при моём "подходе" формула шибко длинная будет.. много вложений) 2. выбрал цвет изделия - тут ровно все 3. должно под грузиться число (по которому идет округление заказа)
__________________
Век живи, Век - учись Последний раз редактировалось konstruktor; 16.07.2010 в 11:10.. |
|
|
|
|
|
|
#432
|
|||||||||||||||||||||||
|
Неактивный пользователь
Пол:
Регистрация: 16.09.2008
Сообщений: 28
Репутация: 8
|
Этот код не работает... Работает от The_Prist и от DmitriC Всем спасибо!!! ![]() |
|||||||||||||||||||||||
|
|
|
|
|
#433
|
|||||||||||||||||||||||
|
Постоялец
![]() ![]() ![]() Пол:
Регистрация: 22.11.2006
Сообщений: 328
Репутация: 108
|
В общем, смотри что получилось. Это только предварительное упрощение, т. к. непонятен смысл таблицы "материалы (листов)" на листе"производство), а именно почему в ячейках этой таблицы устанавливаются полные суммы. Я пометил желтым то, что мне неясно. Ну и из листа "заявки" выброшены все промежуточные расчеты, т. к. они не нужны. Изменения сделаны только для товаров первой группы. Остальное - по аналогии. primer Последний раз редактировалось DmitriC; 19.07.2010 в 16:49.. |
|||||||||||||||||||||||
|
|
|
| Сказали спасибо: |
|
|
#434
|
|
лист "производство" - это отчет цеха по материалам.
лист "предметы" - справочник (название, кол-во для оптимального заказа), кол-во материалов, кол-во фурнитуры там в формуле идет проверка двух условий: 1. название предмета 2. цвет выявив "нужный" предмет, табл. выясняет цвет, затем в ячейку ставится кол-во листов данного цвета З. Ы. за формулу реально спасибо, много короче.. выходит... только она выдает номер позиции, а нужно число (оно не совпадает с номером позиции) - кол-во для оптим. раскроя (столбец D на листе !предметы) чувствую что нужен ВПР но не могу с ним совладать...
__________________
Век живи, Век - учись Последний раз редактировалось konstruktor; 20.07.2010 в 06:47.. |
|
|
|
|
|
|
#435
|
|||||||||||||||||||||||
|
Постоялец
![]() ![]() ![]() Пол:
Регистрация: 22.11.2006
Сообщений: 328
Репутация: 108
|
В таком случае формулу можно заменить на: Код:
=ЕСЛИ(ЕПУСТО(B4);;ИНДЕКС(предметы!D$4:D$23;ПОИСКПОЗ(B4;кухонные_уголки;0))) ![]() Заодно вопрос: если несколько раз выбрать один и тот же товар ОДНОГО цвета, то в таблице "материалы (листов)" каждый раз напротив выбранного товара указывается суммарное количество предметов (я этот момент желтым цветом пометил). Так и должно быть, или это у тебя ошибка? Потому что с формулами в этой таблице тоже надо что-то делать и перед переделкой хочется быть уверенным, что там ничего не напутано. Последний раз редактировалось DmitriC; 20.07.2010 в 08:51.. |
|||||||||||||||||||||||
|
|
|
| Сказали спасибо: |
![]() |
Похожие темы
|
||||
| Тема | Автор | Раздел | Ответов | Последнее сообщение |
| ЛовиОтвет (Лови ответ) - решение задач и примеров по математике | Евгений92752 | Freeware софт | 7 | 27.05.2015 07:29 |
| конвертер PDF to Excel | master05 | Скорая помощь | 4 | 12.08.2011 14:37 |
| EXCEL в Delph 7. | Toxa07 | Delphi | 5 | 18.05.2009 19:49 |
| Как разблокировать диспетчер задач «Диспетчер задач отключен Администратором». | Rench1k | Microsoft Windows | 20 | 30.01.2009 10:18 |
| VCL для Excel | Embolus | Delphi | 26 | 13.11.2008 23:25 |
|
|