Dim sPath1 As String
Dim sPath2 As String
sPath1 = "C:\Program Files\My App"
sPath2 = "C:\Program Files\My App\Data\Frd"
Dim Result As String
Result = Mid$(sPath2, Len(sPath1) + 1)
'или
Result = Replace(sPath2, sPath1, "")
'*************************************************************
' Функция возвращает относительный путь, сформированный из
' базового пути и абсолютного
'*************************************************************
Public Function GetRelPath(ByVal sSrcPath As String, ByVal sAbsPath As String) As String
Dim sAddPath As String, i As Integer
If Len(sSrcPath) < 2 Then GetRelPath = sAbsPath: Exit Function
If Right$(sSrcPath, 1) <> "\" Then sSrcPath = sSrcPath & "\"
If Left$(sSrcPath, 2) = "\\" Then
i = InStr(3, sSrcPath, "\")
Else
i = InStr(sSrcPath, ":\")
If i > 0 Then i = i + 1
End If
If i = 0 Then GetRelPath = sAbsPath: Exit Function
If 0 <> StrComp(Left$(sSrcPath, i), Left$(sAbsPath, i)) Then GetRelPath = sAbsPath: Exit Function
Do
If 0 = StrComp(sSrcPath, Left$(sAbsPath, Len(sSrcPath)), vbTextCompare) Then Exit Do
sAddPath = sAddPath & "..\"
i = InStrRev(sSrcPath, "\", Len(sSrcPath) - 1)
sSrcPath = Left$(sSrcPath, i)
If i = 1 Then Exit Do
Loop
If Len(sAddPath) Then
GetRelPath = sAddPath & Mid$(sAbsPath, Len(sSrcPath) + 1)
Else
GetRelPath = Mid$(sAbsPath, Len(sSrcPath) + 1)
End If
End Function
'//------------------------------------------------------------------------------------
Dim vArray As Variant, sPathString As String
Dim sRelativePath As String
'//------------------------------------------------------------------------------------
sPathString = "C:\Program Files\My App\Data\Frd"
vArray = Split(sPathString, "My App", , vbTextCompare)
sRelativePath = vArray(UBound(vArray))
А если так:
Andrey Fedorov писал(а):А если так:
Нет. Правильный ответ - пользовать PathRelativePathTo.
Ибо эта функция и даст нужный результат.
'//------------------------------------------------------------------------------------
Dim sPathString As String
Dim sRelativePath As String, sAppPath as String
'//------------------------------------------------------------------------------------
sPathString = "C:\Program Files\My App\Data\Frd"
sAppPath = "C:\Program Files\My App"
sRelativePath = Replace(sPathString, sAppPath, "")
alibek писал(а):Тем не менее есть решения неправильные. И заменять системные процедуры своими неправильно. Правильно -- использовать API.
Есть решения, которые работают и решения, которые не работают.
alibek писал(а):Возьмем твой пример.
Как он сработает, если исходный путь C:\Dir1\Dir2, а путь, относительно которого надо построить ссылку будет C:\Dir1\Dir2\Dir3\C:\Dir1\Dir2\Dir4\Dir5? (оставим то, что он задан некорректно).
Или, например, том C: является специальным устройством и в нем нельзя использовать относительную адресацию?
Andrey Fedorov писал(а):To:SedgeЕсть решения, которые работают и решения, которые не работают.
Золотые слова - попробуй свою вариант, к примеру, со следующими параметрами:
The relative path is relative from: c:\a\b\path
The relative path is relative to: c:\a\x\y\file
alibek писал(а):То, чтобы PathRelativePathTo всегда отрабатывал правильно -- это забота разработчиков ОС.
Можно самому выделять буферы, рисовать в видеопамяти, реализовать свою систему фонтов и не использовать возможности GDI. Только смысл этого?
Прочти постановку задачи. Где сказано что относительный путь необходимо получать из вложенного фолдера?
Это все очень хорошо, но кто объяснит данную проблему заказчику?
Andrey Fedorov писал(а):Прочти постановку задачи. Где сказано что относительный путь необходимо получать из вложенного фолдера?
Как правило его надо получать из каталога где находится программа. В общем, нужно делать так как делает сам VB в своем файле проекта.
А он может быть каким угодно (в том числе и вложенным).Это все очень хорошо, но кто объяснит данную проблему заказчику?
А ему не надо объяснять - у него должно просто работать. В случае с API-функцией за нас эту проблему уже решили. А в случае с твоим решением - идут твои отговорки (см начало этого письма!).
Sedge писал(а):Если относительный путь надо получить из того каталога, где находится программа, то мой способ работает. Не спорю, твой работает тоже, но, имхо, он избыточен. Про вложенные фолдеры в вопросе не было ни слова.
Думаем внимательно, да? Если относительный путь надо получить из того каталога, где находится программа, то мой способ работает.
Не спорю, твой работает тоже, но, имхо, он избыточен.
Конечно, я понимаю, что на декларациях внешних библиотек, растянувшихся на два экрана,
но зачем придумавать задачи, которые перед тобой никто не ставит?
Sedge писал(а):Если мне надо найти максимум из трех двухзначных чисел, я найду максимум из трех двухзначных чисел, а не буду вызывать API-функцию, которая сделает то же самое, но в добавок еще понимает шестнадцатиричное представление числа, использует нелинейную оптимизацию, вышивает крестиком и поддерживается всеми версиями Windows, начиная с Longhorn'а SP1.
Andrey Fedorov писал(а):Думай внима-а-а-ательно еще раз:
Текущий путь: C:\Work\MyProg\Prj
Надо найти относитальный путь к C:\Work\Lib\VB\Modules
То есть нужно получить ..\..\Lib\VB\Modules
alibek писал(а):И неправильно сделаешь. Потому что API это "Application Programming Interface". И если в этом программном интерфейсе есть функция определения максимума из трех чисел, надо использовать не самописную функцию, а именно ее, пусть даже для этого и требуется инициализировать 200-байтную структуру, расставить идентификаторы безопасности и получить привилегии для указанной работы.
Ты же стараешься перекрыть все возможные варианты, достигнув 100% гарантии нормальной работы программы.
когда недокумментированные функции, которыми я пользовался, сказали "мяу".
Private Declare Function PathRelativePathTo Lib "shlwapi.dll" Alias "PathRelativePathToA" _
(ByVal pszPath As String, ByVal pszFrom As String, ByVal dwAttrFrom As Long, _
ByVal pszTo As String, ByVal dwAttrTo As Long) As Long
Private Const MAX_PATH As Long = 260
Private Function GetRelPath(sFrom As String, sTo As String) As String
Dim s As String * MAX_PATH
If PathRelativePathTo(s, sFrom, 16, sTo, 128) Then
GetRelPath = Left$(s, InStr(s, vbNullChar) - 1)
Else
GetRelPath = sTo
End If
End Function
ты никогда не использовал VarPtr/StrPtr/ObjPtr?
GSerg писал(а):Я вот только их и... Но при этом решений на 99% не приемлю
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14