Страницы: 1
RSS
Изменить фрагменты текста и сцепить их обратно
 
Допустим я хочу поменять часть текста в ячейках
Код
Sub test()
Dim element As Range, a As Variant 'цикл по ячейкам

  For Each element In Selection
       a = element.Value 'значение конкретной ячейки
       a = VBA.Split(a, ", ") ' отделяем на части по критерию ", "
       n = UBound(a) 'a(n) это последнее после запятой с пробелом , т.е. если у нас было "мама, папа, брат", то получим a(n)=Брат

       msgBox a(n)
  Next  
End Sub

А как теперь к этому a(n) применить макрос и вернуть все в зад но с изменениями? Допустим если замена
Код
a(n) = Replace(a(n), одно, другое)

, то это же как то надо записать все назад ( причем у меня в замене еще пара циклов, по этому думал что проще сослаться на макрос)

Хотя бы верной ли логикой я иду? Как понимаю теперь нужно назад  что-то типа сцепить LBound(a) to [UBound(a)  - 1] + a(n)?
 
Перебираем элементы массива  и на каждом шаге сцепляем полученные значения:
Код
aSpl =Split(element.Value, ", ") 

For j = 0 To Ubound(aSpl)
     If aSpl(j) <> "майка с фуфайкой" Then
          sText = sText & ", " & Replace(aSpl(j),"майка", "фуфайка")
     Else
          sText = sText & ", " & aSpl(j)
     End If
Next j

sText  =Mid$(sText,3)
 
, че то не пойму,  по коду он берет текст ячейки, разбивает по запятой с пробелом, в этих кусках ищет и меняет майку на фуфайку, если нашел меняет, если не нашел втавляет без изменений , я правильно его понял? с sText  =Mid$(sText,3) не разобрался, в справке пока не прозрачно. почему 3

А я ворочу другое , он взял одну ячейку, взял последний "хвост после запятой" в нем произвел замену, и вернул все но с правками
Код
Sub test()
Dim aSpl As Variant
Dim АБВ, a, sText, aSplf, aSpln As String
Dim element As Range 'объявляем переменные

  For Each element In Selection 'идем по ячейкам

a = element.Value 'берем ячейку
aSpl = Split(a, ", ") 'делаем из нее масив
aSpln = UBound(aSpl) 'определяем последнее после запятой
aSplf = aSpl(aSpln)'берем последнее после запятой

' в этом хвостике прогоняем по ряду правил
АБВ = Array("первое", "пятое", "десятое")
For i = 0 To UBound(АБВ)
For x = 0 To 9
sText = Replace(aSplf, x & " " & АБВ(i), x & АБВ(i)) ' по идее получаем исправленный хвостик в данном примере между цифрой и пятым\десятым удаляем пробел, отдельно такой макрос работает

Next x
Next i

' конец замены в этом хвостике 
finish = a & sText
element.Value = finish ' записываем как было, только с исправленным хвостиком, вот тут и ошибка

    Next' переходим к следующей ячеке
End Sub

явно финиш не верен, или не верно все? sText = Replace не отрабатывает
надо из а вычленить aSplf , т.е математически finish = a -aSpl  & sText
Изменено: mihail_ms - 17.02.2022 21:53:41
 
Цитата
mihail_ms написал: с sText  =Mid$(sText,3) не разобрался, в справке пока не прозрачно. почему 3
Потому что пустоту объединяем с первым фрагментом тоже через разделитель (2 символа):
Код
 sText  = ", фрагмент1, фрагмент2, фрагмент3..."


Цитата
нужно ли в этом нексте писать i?
Не обязательно, но рекомендую. И объявлять переменные надо все.
aSpl - у Вас то массив, то переменная с одним значением.
 
насколько читал переменную можно объявлять сколь угодно раз,  актуально последнее, по этому думал aSpl  в 1й раз масив, что бы в нем вычленить хвостик, а второй раз как сам хвостик, ну ок, ввел\изменил на еще одну переменную aSplf(есть подозрение, что половину можно не объявлять, но для наглядности и пошаговости без этого пока не куда)

сам код в сообщении 3
 
Если исправления нужно внести только в последний фрагмент текста:
Код
    sText = element.Value
    n = InStrRev(sText, ",") ' n - положение последнего разделителя
    sTextRight = Mid$(sText, n + 2) ' n + 2 - положение символа после разделителя
    '
    ' здесь меняем майку на фуфайку
    '
    element.Value = Left$(sText, n + 1) & sTextRight  ' n + 1 - положение второго символа разделителя


Цитата
переменную можно объявлять сколь угодно раз,  актуально последнее
Не путайте объявление переменных и их изменение.
Объявление - это когда под переменную выделяется определенный объем  памяти:
Код
Dim aSpl
Dim i As Long, dDate As Date

Менять назначение переменных по ходу выполнения кода можно, но не всегда это оправдано - можна запутаться, читая такое творение. Да и при написании можно наловить ошибок.

P.S. Я уже запутался в похожих именах )
aSpln = UBound(aSpl) ' определяем последнее после запятой число - количество элементов массива
aSplf = aSpl(aSpln) ' из массива получаем значение последнего элемента
 
дай Бог Вам здоровья,
в будущем постараюсь придумать имена переменным более разнообразные и креативные, сейчас менять  не надо, а то совсем запутаюсь(возможно не только я)
в принципе оно, но все равно не работает))) выдает как и было, начал разбираться не работает замена

метод Range.Replace работает, а метод Replace(где,что, на что) почему то нет, попробовал отдельно,

работает
Код
АБВ = Array("первое", "пятое", "десятое")
For i = 0 To UBound(АБВ)
For x = 0 To 9
Selection.Replace x & " " & АБВ(i), x & АБВ(i)
Next
Next

не работает
Код
переменная=element.Value
АБВ = Array("первое", "пятое", "десятое")
For i = 0 To UBound(АБВ)
For x = 0 To 9
sText = Replace(переменная, x & " " & АБВ(i), x & АБВ(i)) 
Next x
Next i
element.Value=sText 
причем x & " " & АБВ(i), x & АБВ(i) заменить на пару статичных значений, да хоть на "1", "2", то работает

скорее бы выходные, может просто я разбираюсь без бутылки, по этому так сложно разобраться?  )))

было уже обрадовался что увидел свет в конце тонеля, т.к. мелькнула мысль через InStrRev и mid определить положение и добавить параметр Start, но нет.
(лирическое отступление,  можно же пойти другим путем, определить последнюю запятую и все замены производить после нее, была мысль, но почемуто вспомнились формулы с поискпоз и меня проняла дрожь)
метод  Range.Replace не имеет такого параметра как start в отличии от метод Replace(где,что, на что)

P/s/ я не здаюсь, буду пробовать дальше...
 
Цитата
mihail_ms написал: определить последнюю запятую и все замены производить после нее
Именно это я Вам показал в последнем примере.
Как расцеплять и сцеплять после замены разобрались?
 
,в принципе да, но вообще изначально тема называлась чуть иначе,что то типа как применить макрос к переменной... ну и плавно пришли к чему прешли...

по сцепке, расцепке еще вникаю, в общех чертах да, но вот эти +n -n   всегда промахиваюсь), кароч раздел VBA Excel. Работа с текстом (функции)
Изменено: mihail_ms - 17.02.2022 23:43:21
 
Цитата
mihail_ms написал: метод Range.Replace работает, а метод Replace(где,что, на что) почему то нет
Работает, но так, как Вы написали )
Код
For x = 0 To 9
Selection.Replace x & " " & АБВ(i), x & АБВ(i)
Next х

В выбранном диапазоне 10 раз пытаетесь произвести замену (и заменяете, если искомое есть). При этом после каждого изменения  происходит накопление замен.
А здесь:
Код
For x = 0 To 9
sText = Replace(переменная, x & " " & АБВ(i), x & АБВ(i)) 
Next x

при каждой итерации значение sText затирается и записывается новое. Из цикла х выходит только одно последнее изменение. А в ячейку (после цикла i) записывается только это значение sText :
Код
sText = Replace(переменная, "9 десятое", "9десятое")   

А попробуйте записать так:
Код
переменная = Replace(переменная, x & " " & АБВ(i), x & АБВ(i)) 
'и после выхода из циклов 
element.Value =  переменная


Уходим от темы. Все-таки здесь главный вопрос - найти, где расцепить и как сцепить после замены.
Дальнейшее обсуждение замен не в этой теме.

P.S. Не давайте переменным имена типа переменная!!!
Я написал текст, потом пришлось подправлять, иначе упоминание переменной sText (без указания имени) могло быть понято, как упоминание имени переменная
 
, я все таки отвечу тут, и далее по замене не жду пояснений в этой теме, да и другая тема увы не сегодня.

element.Value =  переменная пробовал, впрочем смотрю через
Код
msgbox переменная

а что касается методов, то на выходе то получим одно и тоже т.к. накопление замен может встретиться может только единожды, по краййней мере в моем случае( он же ищет пробел между цифрой и буквой, и перебирает все варианты), хотя конечно может наверное и нет... уф.

P/S за опечатки ссори, т.к. через рдп, с плохим интернетом, и из-за лагов то 2 знака, то не тот и не увидел, то не тот порядок...
 
Чтобы понять, что там  творится "в Вашем случае", нужно видеть пример данных и нормальное описания задачи, а не прыгания с одного на другое. Но не в этой теме.
 
Кароч дожал, чуть не .... не будем об этом))


Код
 For Each element In Selection
sText = element.Value
    n = InStrRev(sText, ",") ' ищем положение зпт с конца(номер символа в строке)
    n = n + 1' зачем то добавляем 1 )))  без этого не работает

    
  ÀÁÂ = Array("À", "Á", "Â")' добавляем всякие условия

For i = 0 To UBound(ÀÁÂ)
For x = 0 To 9

sTextREP = Replace(element.Value, x & " " & ÀÁÂ(i), x & ÀÁÂ(i), [n])'ищем\заменяем где n это начало откуда ищем 


element.Value = Left$(sText, n - 1) & sTextREP'и каждый раз записываем изменения


Next x
Next i
 
   
   ' MsgBox element.Value
    
    Next 'и так по кругу

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

Изменено: mihail_ms - 18.02.2022 01:43:31
 
Цитата
mihail_ms написал: дожал...
... до множества бесполезных действий :)
 
,нет предела совершенству, я вот впервые столкнулся с автоматизацией и мой корявый код отрабатывал 40 минут, сейчас уже 6-8, а завтра глядишь и на 3 выйду))) но это все равно лучше, чем верстать в ручную пол дня начальнику очередную бесполезную табличку, которую он толком и не посмотрит, но делать надо...
Изменено: mihail_ms - 18.02.2022 02:12:08
Страницы: 1
Наверх