Function Read_INI()
Dim s As String
Key$ = "HKEY_CURRENT_USER\Software\VisaCreator\InstallPath"
s = CreateObject("WScript.Shell").RegRead(Key$)
MsgBox s
End Function
Я с реестрами никогда не работал... пока что "чайник" видимо Однако прописать в инсталлятор загрузку в реестр данных не вопрос А как потом оттуда извлечь путь То есть какие дальнейшие действия? БМВ, я Вам благодарен за совет...
Нашел практичное решение: В установочный пакет, по совету мудрых людей, добавил текстовый файл *.ini в раздел "C:\Windows" Осталось понять теперь как извлечь оттуда путь к программе. В данном файле *.ini имеются следующие записи
Цитата
[InstallSettings] InstallPath=C:\Visa Creator
Создал функцию просмотра первой строчки файла
Код
Function Read_INI()
Open "C:\Windows\visacreate.ini" For Input As #1
Dim s As Variant
Input #1, s
MsgBox s
End Function
Как и ожидалось вышло сообщение с текстом [InstallSettings] Все работает. Осталось прочесть вторую строчку без "InstallPath=" Видимо нужно через EOF (идентификатор) Пока не разобрался... Есть ли простой метод извлечения? я так понимаю количество знаков до "C:\Visa Creator" неизменно Left(String, Length)
Настройте установщик так, чтобы он прописывал в пользовательский раздел реестра данные о том, куда была установлена программа
интересное решение Нашел в папке с установленной программой деинтсталлятор вида "unins000.dat", в котором очень четко прописан путь откуда нужно удалять программу...
Доброго времени суток! Есть рабочий Проект на основе Microsoft Excel. По сути программное обеспечение. Инсталлируется установщиком в указанную пользователем папку . Проект прекрасно работает, запускается, код защищен и т.д. Но возникла проблема из-за ошибочных путей к рабочим файлам они не открываются, так как ссылаются на временную папку, а нужен правильный путь к установленной программе. Иными словами, адрес по которому находится сам исполняемый файл: Excel.exe.
Цитата
ThisWorkbook.Path
неплохо справляется с задачей. Также как и
Цитата
ActiveWorkbook.Path
Но проблема в том что после конвертации *.xls в *.exe все это сыпется. Эти же самые операнды не отображают реального расположения файла. Что конечно же правомерно, так как все действия переносятся в папку Temp. После чего тот же
Цитата
ThisWorkbook.Path
прописывает путь к временно созданной внутри себя папке:
Цитата
C:\Users\Пользователь\AppData\Local\Temp\XL181124191800_tmp\XLtmp\Visa Base
Хотя должно быть:
Цитата
C:\Visa Creator\Visa Base
А в этой папке \Visa Base и в корневике хранятся все рабочие файлы к которым нужно постоянно обращаться, менять, сохранять, справка CHM, Readme.txt и т.д и т.п. То есть весь проект ломается из-за ложных путей. Понятно, что можно просто прописать четкий путь. Но часто при инсталляции пользователи ставят программу куда захотят. Кто-то может знает пути решения этой головоломки? Какие есть способы "найти себя", не заглядывая в ветку Temp. Может например при открытии книги как то вычислять путь. Или есть какие то другие способы. Помогите советом пожалуйста!
К сожалению процедура по прежнему прерывается. Мест где пароль присваивается всего несколько. Пробовал отключать. Возможно, что пароль включается раньше завершения изменения ячеек. События меняются более чем в 30 ячейках за 1 раз. Идет присваивание ячейкам пользовательских значений. Однако пауза тоже не решила проблему:
Надо сказать что включение пароля вызывает ошибку именно в завершении этой процедуры
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Другие процедуры нормально реагируют на включение/отключение защиты. Файл выслать не могу - в нем конфиденциальная информация. Приложение работает с анкетами.
Доброго времени суток! Имеется приложение в Excel, некоторые ячейки которого хотелось бы защитить. Не столько скрыть формулы - сколько просто от случайного стирания. Что разумеется легко решается. Ничего нового - тема стара как мир и решается через Protect. На всех процедурах: Sub ... End Sub все прекрасно работает. Однако когда дело доходит до процедур изменения ячеек с последующими действиями исполнение кода завершается ошибкой. То есть при появлении завершающего присваивания пароля:
Код
Worksheets("List1").Protect Password:="555"
Процедура вылетает. Ошибка вида: Run Time Error '1004'
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Application.ScreenUpdating = False
Worksheets("List1").Unprotect Password:="555"
'много ячеек подверженных изменению
Set KeyCells = Range("B1")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
'необходимые действия
Set KeyCells = Range("B2")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
'необходимые действия
'и так далее
Worksheets("List1").Protect Password:="555"
End Sub
Может кто сталкивался с подобным и знает простое решение. По сути нужно защитить даже не лист а просто диапазон ячеек на листе. Формулы в этих ячейках тоже желательно все-таки скрыть. Заранее благодарен за советы и решения
Range("A2").Count=1 (одна ячейка), так что цикл проходится ровно 1 раз -> цикл не нужен.
Без оператора цикла For...Next поля не наполняются данными последовательно при выборе нового значения из списка
Цитата
Вам нужен второй проход функции при изменении А3 или А4?
Нет второй проход не нужен. Нужно завершить процедуру и как-то удалить оставшиеся запятые в конце обеих строчек. Сложность в том что длина строки всегда будет разной и не обязательно равняться 50. То есть надо видимо каким то образом найти эту запятую в конце строчки после заполнения и потом уже удалить. Если на конце строки нет запятой то все в порядке. При этом остальные запятые в середине поля не должны пострадать. Иначе будут удаляться все запятые сразу при их появлении. Не могли бы привести в нормальный вид весь код? То есть вместо Х, Y,... Z, должно остаться Х, Y,... Z
'Заполняем поля посещения стран автоматически
Private Sub Worksheet_Change(ByVal Target As Range)
Set KeyCells = Range("A2")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
Application.ScreenUpdating = False
Dim str As String
Dim i As Long
For i = 0 To Range("A2").Count - 1
If Range("A2").Select Then
str = str & Range("A2").Value & ", "
End If
Next
If Len(Range("A3").Value & str) < 50 Then
Range("A3").Value = Range("A3").Value & str
ElseIf Len(Range("A4").Value & str) < 50 Then
Range("A4").Value = Range("A4").Value & str
End If
End If
Есть простой вопросик, может кто сталкивался. Возникла необходимость заполнять поля А3 и А4 (это для анкеты) данными из списка А2 При выборе значения из списка оно наполняет нижнее поле.
При достижении длины поля более 50 знаков необходимо перейти на нижнюю строчку а при достижении 50 знаков остановить процесс. Желательно чтобы после завершения всего процесса последняя запятые в верхнем и нижнем поле были удалены.
Код
'Заполняем поля посещения стран автоматически
Private Sub Worksheet_Change(ByVal Target As Range)
Set KeyCells = Range("A2")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
Application.ScreenUpdating = False
Dim str As String
Dim i As Long
For i = 0 To Range("A2").Count - 1
If Range("A2").Select Then
str = str & Range("A2").Value & ", "
End If
Next
Range("A3").Value = Range("A3").Value & str
End If
End Sub
В принципе все теперь понятно. Все работает если убрать проверку ошибки Пытаюсь переделать Ваши решения под старый Excel Отпишусь если получится... Всем спасибо!
Проверил сейчас. К сожалению замена на ЕОШ и тп не сработала Но все равно О-огромное спасибо за помощь! Пытаюсь сделать: =ЕСЛИ(ДЛСТР(B5)<$B$1;B5;ПСТР(B5;1;$B$1-$C$1+НАЙТИ(" ";ПСТР(B5;$B$1-$C$1+1;$C$1))));ЕСЛИ(ДЛСТР(B5)<$B$1;B5;ПСТР(B5;1;$B$1-$D$1+НАЙТИ(" ";ПСТР(B5;$B$1-$D$1+1;$D$1)))) но выдает #знач!
Решение на одной из веток форума, подкорректировал. Для первой результирующей ячейки: =ПСТР(N6;1;ПРОСМОТР(2;1/(ПСТР((N6)&" ";СТРОКА($1:$36);1)=" ");СТРОКА($1:$36))) Но все равно вопросы остались. Думаю, что в этой формуле есть лишние функции Не понимаю что делает функция СТРОКА($1:$36);1)=" " и как затем получить строчку номер 2 и 3?
Вопрос конечно не новый. Однако красивого решения так и не смог найти. При заполнении анкет на сайтах часто возникает необходимость вбить длинный текст в несколько полей. То есть имеется определенная ячейка с текстовой строкой (в данном случае адрес отеля) с количеством символов от 10 до 105. Нужно разбить этот текст на три части длиною не более 35 символов и вставить в 3 ячейки. Слова конечно же отделены пробелом и их нельзя дробить. Например исходная строка: VAMANA TRAVELS INDIA PVT LTD FF10, ANSAL FORTUNE ARCADE, SECTOR 18, NOIDA 201301 А необходимо получить: VAMANA TRAVELS INDIA PVT LTD FF10, ANSAL FORTUNE ARCADE, SECTOR 18, NOIDA 201301
Задача казалось бы простая, но на практике так и не смог получить эффективное решение несколькими формулами. Приходится проводить множество операций. Сначала разбивать текст на слова. Потом вычислять их длину. Потом "склеивать" их по признаку чтобы в строке было не более 35 символов. Может есть какое то простое решение... Заранее спасибо!
Вот именно, обращаться не нужно, если удален. То есть при выборе других листов не нужно все время заново удалять уже удаленный диапазон а как решить не знаю
Код
If ActiveWorkbook.Names("Рисунок")="" Then
Exit Sub
Else
ActiveWorkbook.Names("Рисунок").Delete
End If
но почему-то не срабатывает - а я не особо силен в vba
Цитата
При активации листа создается имя, при выходе с листа имя удаляется
Спасибо это действительно хорошее решение - что то не подумал об этом сразу но все равно интересно решить задачку с проверкой наличия имени в Рабочей книге
Имеется диапазон с определенным именем (в моем случае имя "Рисунок") Это имя + формула присваивается при активации отчетного листа Это необходимая мера так как наличие формулы у этого имени сильно тормозит систему (связано с отображением графических файлов на отчетном листе) Поэтому и было принято данное решение: создавать-удалять имя При переходе на другой лист имя "Рисунок" успешно удаляется - кликаем лист "Отчет" снова создается. Все работает на "ура" но при двойном переходе к последующему листу, минуя "Отчет", Excel естественно ругается, так как диапазона с таким именем не существует.
Вопрос очень простой: как проверить наличие определенного имени в ActiveWorkbook.Names и при его отсутствии выйти из процедуры удаления имени.
Теперь осталось понять каким макаром определить какой из выключателей с именами X1, X2, X3 и X4 сейчас включен (имеет Value = True) и передать полученное значение i (от 1 до 4) в следующую процедуру
следующий код что-то глючит...
Код
Dim i As Long
For i = 1 To 4
If Me.OLEObjects("X" & i).Object.Value = True Then
Range("A20").Value = i
End If
Next
В ячейку выдает всегда единичку и то только когда включен выключатель с именем X1 пишу
Код
Dim i As Long
For i = 1 To 4
If Me.OLEObjects("X" & i).Object.Value = False Then
Range("A20").Value = i
End If
Next
тогда выдает четверку и опять так игнорирует включение других выключателей Кто-то может помочь разобраться?