Помогите переписать функцию по-человечески

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
VBChild
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.10.2022 (Сб) 23:20

Помогите переписать функцию по-человечески

Сообщение VBChild » 13.04.2023 (Чт) 2:41

Привет всем! Я дико извиняюсь за бред, который вы увидете ниже. Но я только учусь программировать.

Ситуация следующая: Я маунчу сетевой каталог, как диск. Чтобы далее с файлами на нём работать уже по локальным путям, а не unc.
Код: Выделить всё
Option Explicit

Private Const NO_ERROR = 0
Private Const CONNECT_UPDATE_PROFILE = &H1
Private Const RESOURCE_GLOBALNET = &H2
Private Const RESOURCETYPE_DISK = &H1
Private Const RESOURCEDISPLAYTYPE_SHARE = &H3
Private Const RESOURCEUSAGE_CONNECTABLE = &H1

Private Type NETRESOURCE
    dwScope As Long
    dwType As Long
    dwDisplayType As Long
    dwUsage As Long
    lpLocalName As String
    lpRemoteName As String
    lpComment As String
    lpProvider As String
End Type

Private Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" (lpNetResource As NETRESOURCE, ByVal lpPassword As String, ByVal lpUserName As String, ByVal dwFlags As Long) As Long

Public Function MountNetFolder(ByVal UNCPath As String, ByVal DriveLetter As String) As Boolean
    Dim NetR As NETRESOURCE
    Dim ErrInfo As Long
   
    If IsValidDriveLetter(DriveLetter) = False Then
        MountNetFolder = False
        Exit Function
    End If
   
    With NetR
        .dwScope = RESOURCE_GLOBALNET
        .dwType = RESOURCETYPE_DISK
        .dwDisplayType = RESOURCEDISPLAYTYPE_SHARE
        .dwUsage = RESOURCEUSAGE_CONNECTABLE
        .lpLocalName = DriveLetter 'Óêàçûâàòü ñ äâîåòî÷èåì
        .lpRemoteName = UNCPath
    End With

    ErrInfo = WNetAddConnection2(NetR, vbNullString, vbNullString, CONNECT_UPDATE_PROFILE)
   
    MountNetFolder = IIf((ErrInfo = NO_ERROR), True, False)
End Function


Проблема с дочерней функцией IsValidDriveLetter

Далее идёт полнейший бред, который ещё и криво работает. Сильно не бейте.
Код: Выделить всё
Private Function IsValidDriveLetter(ByVal DriveLetter As String) As Boolean
    DriveLetter = UCase$(DriveLetter)
    '1 - Z     2 - Z:
    If Len(DriveLetter) = 0 Or Len(DriveLetter) > 2 Then
        IsValidDriveLetter = False
        Exit Function
    End If
    'Задана только буква
    If Len(DriveLetter) = 1 Then
        If StrComp(DriveLetter, "A", vbTextCompare) <> 0 Then
            IsValidDriveLetter = False
            Exit Function
        End If
       
        If StrComp(DriveLetter, "B", vbTextCompare) <> 0 Then
            IsValidDriveLetter = False
            Exit Function
        End If
       
        If StrComp(DriveLetter, "C", vbTextCompare) <> 0 Then
            IsValidDriveLetter = False
            Exit Function
        End If
       
        DriveLetter = DriveLetter & ":"
    End If
    'Задана буква и второй символ (ожидается двоеточие)
    If Len(DriveLetter) = 2 Then
        If Mid$(DriveLetter, 2, 1) <> ":" Then
            IsValidDriveLetter = False
            Exit Function
        End If
       
        If StrComp(DriveLetter, "A:", vbTextCompare) <> 0 Then
            IsValidDriveLetter = False
            Exit Function
        End If
       
        If StrComp(DriveLetter, "B:", vbTextCompare) <> 0 Then
            IsValidDriveLetter = False
            Exit Function
        End If
       
        If StrComp(DriveLetter, "C:", vbTextCompare) <> 0 Then
            IsValidDriveLetter = False
            Exit Function
        End If
    End If
   
    IsValidDriveLetter = True
End Function


То есть, мне надо проверить валидность имени диска, перед тем, как маунтить на него сетевой ресурс. Я понимаю, что такая проверка делается строк в 5 кода.

Далее я напишу функцию проверки, не занята ли данная буква диска. Заранее - огромное спасибо!

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 13.04.2023 (Чт) 18:36

Не совсем понял, что конкретно вам нужно, но может вам поможет стандартный элемент управления VB DriveListBox... ??? Можно сразу получить все доступные диски.

VBChild
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.10.2022 (Сб) 23:20

Re: Помогите переписать функцию по-человечески

Сообщение VBChild » 14.04.2023 (Пт) 2:49

Vova_2581 писал(а):Не совсем понял, что конкретно вам нужно, но может вам поможет стандартный элемент управления VB DriveListBox... ??? Можно сразу получить все доступные диски.


У меня Dll. никакого интерфейса - нет.

Когда подключаешь сетевую папку, как диск, то требуется задать букву этого диска. Запрещены буквы: A,B и буквы всех занятых дисков. Вот я и не могу написать нормальную функцию, проверки буквы диска.

Вызов функций dll, выглядит так:
Код: Выделить всё
Const DriveLetter = "Z:"
Const BuildPath = "\4.2\4.2.21.58.rev.34115\ClientReleaseRus_msiWin32\DiskImages\DISK1"
Dim MCEQA

Set MCEQA = CreateObject("MCEQACore.cSupport")

With MCEQA
   .MountNetFolder "\\dc2\ReleaseBuilds", DriveLetter
   .CopyFolder DriveLetter & BuildPath, "D:\Dest" , false
   .UnMountNetFolder DriveLetter
End With

Set MCEQA = nothing


Тело функции MountNetFolder - описано в вопросе. Вот там нужно вызвать функцию (IsValidDriveLetter), для проверки заданной буквы диска: что значение не равно: A , B , C , A: , A:\ , B:\ , C:\, каля-маля, и прочие неподходящие вариации.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 14.04.2023 (Пт) 6:57

Ну тогда может быть исходить из логики не проверки недоступных дисков, а из логики получения сразу доступных дисков... Как вариант...
http://www.vbnet.ru/forum/show.aspx?id=198721

VBChild
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.10.2022 (Сб) 23:20

Re: Помогите переписать функцию по-человечески

Сообщение VBChild » 14.04.2023 (Пт) 7:16

Vova_2581 писал(а):Const DriveLetter = "Z:"
Пользователь задаёт нужную ему букву диска.

Вы код мой вообще смотрели? Из пустого в порожнее переливаем. Я не знаю, как ещё более доходчиво объяснить.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 14.04.2023 (Пт) 9:57

Vova_2581 писал(а):Const DriveLetter = "Z:"

Я об этом не писал.
VBChild писал(а):Пользователь задаёт нужную ему букву диска.

А вы об этом... не писали.

Может быть такой вариант...
Код: Выделить всё
Private Sub Form_Load()
Dim d As String
d = InputBox("Введите букву диска", "Ввод данных", "Z:")
If d = "" Then Exit Sub
MsgBox "Проверка корректности " & d & " " & IsValidDriveLetter(d)
End Sub

Private Function IsValidDriveLetter(ByVal DriveLetter As String) As Boolean
Dim d As String
Dim i As Long
DriveLetter = UCase$(DriveLetter)
For i = 1 To 10
  d = Choose(i, "A", "A:", "A:\", "B", "B:", "B:\", "C", "C:", "C:\", "D:\")
  If DriveLetter = d Then 'Если нашли совпадение с некорректным значением
   IsValidDriveLetter = False
   Exit Function
  End If
Next
IsValidDriveLetter = True
End Function

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 14.04.2023 (Пт) 13:52

Тут ещё может быть такая ситуация, что пользователь может ввести не только букву, а к примеру, цифру "1:\" или символ какой-то "€:", "@:", "&:\\" типа того, нужно дополнительно делать ещё фильтр.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 14.04.2023 (Пт) 16:21

Ну, я понял, что снова почти не угадал... Ок, передаю слово гуру...

VBChild
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 29.10.2022 (Сб) 23:20

Re: Помогите переписать функцию по-человечески

Сообщение VBChild » 15.04.2023 (Сб) 18:07

Раз помогать не хотят, то я решил отделаться малой кровью. Трёх фиксированных дисков, достаточно.
Код: Выделить всё

Public Enum DRIVELETTERS
    DRIVE_X = 0
    DRIVE_Y = 1
    DRIVE_Z = 2
End Enum

Public Function MountNetFolder(ByVal UNCPath As String, ByVal DriveLetter As DRIVELETTERS) As Boolean
    Dim NetR As NETRESOURCE
    Dim ErrInfo As Long
   
    If IsDriveExist(DriveLetter) = False Then
        MountNetFolder = False
        Exit Function
    End If
'дальше код - прежний

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Помогите переписать функцию по-человечески

Сообщение Хакер » 15.04.2023 (Сб) 18:17

Вы что, шутите тут? Один лучше другого предлагает.

Код: Выделить всё
Option Compare Text

Private Function IsValidDriveLetter(ByVal DriveLetter As String) As Boolean
    IsValidDriveLetter = DriverLetter Like "[D-Z]:"
End Function

Вот и вся проверка. Обратный слеш там не нужен. Или, может быть, нужен, но в любом случае, должна быть строгая определённость, должен он там быть или нет, и либо DLL должна отвергать пути без слеша и принимать только со слешем, либо принимать без слеша и отвергать со слешем. Если хочется дать возможность пользователю вводить и так, и сяк, надо эту проблему решать на уровне взаимодействия с пользователем (грубо говоря — на уровне InputBox), и сразу же введённое приводить в такой вид, какой установлен соглашением (между автором DLL и тем, кто использует DLL).

С другой стороны, я вообще не вижу особого смысла в этой проверке, ведь она не отсекает некорректные буквы дисков, которые некорректны в виду того, что диск уже занят. Зачем нужна проверка, если можно смотреть на статус возврата и по ней судить о том, прошло ли всё успешно, или же был указан синтаксически некорректиный диск, или диск был с виду корректным, но он уже занят.

А вот подход, когда функции возвращают только True/False, но никак не выпускают наружу детали о том, что именно не так — достоен критики.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 16.04.2023 (Вс) 8:40

Хакер писал(а):С другой стороны, я вообще не вижу особого смысла в этой проверке, ведь она не отсекает некорректные буквы дисков, которые некорректны в виду того, что диск уже занят. Зачем нужна проверка, если можно смотреть на статус возврата и по ней судить о том, прошло ли всё успешно, или же был указан синтаксически некорректиный диск, или диск был с виду корректным, но он уже занят.

Так автор написал, что далее сделает проверку...
VBChild писал(а):Далее я напишу функцию проверки, не занята ли данная буква диска. Заранее - огромное спасибо!

Кстати тоже вспомнил по Like совсем недавно использовал его в своей программе. И если проблема решается всего одной строчкой, то думаю, что и отдельная Function тут вообще не нужна. Я бы DriverLetter Like "[D-Z]:" использовал прямо в контексте основного кода.
Последний раз редактировалось Vova_2581 16.04.2023 (Вс) 14:11, всего редактировалось 1 раз.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Помогите переписать функцию по-человечески

Сообщение Vova_2581 » 16.04.2023 (Вс) 13:19

P.S. Хакер, наверное параметр Option Compare Text нужно изменить на Option Compare Binary ??? Так как автору нужно, чтобы пользователь вводил только заглавные буквы и без всяких диакритических знаков типа - ї, ѷ, ä, ö, á и т.д., что допускает Compare Text. Либо его вообще убрать, тогда Binary по-умолчанию.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: SemrushBot и гости: 40

    TopList