powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Проблема с функцией UrlEncode
8 сообщений из 8, страница 1 из 1
Проблема с функцией UrlEncode
    #36573142
motorway
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго дня.
В очередной раз у меня появилась проблема, связанная с быстродействием макроса при обработке большого количества данных. Из Эксела на сервер посылается строка, но чтобы все символы правильно доходили, ее нужно закодировать. Это делается с помощью следующей функции:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
Public Function URLEncode_Ascii(ByVal plain_text As String) As String
'кодирует буквы для передачи на сервер
Dim i As Long, ts As String, cur_char As Byte
Dim reserved_symbols_allowed As String, unreserved_symbols As String
Static flagTableInited As Boolean
Static ascii_map( 0  To  255 ) As String

If Not flagTableInited Then
    ' Незарезервированные символы.
    ' Символы допустимые в URL
    unreserved_symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ"
    For i =  1  To Len(unreserved_symbols)
        ascii_map(Asc(Mid$(unreserved_symbols, i,  1 ))) = Mid$(unreserved_symbols, i,  1 )
    Next i
    ' Зарезервированные символы: !*'();:@&=+$,/?%#[] и пробел
    ' Спецсимволы которые не должны появляться в URI.
    ' Но в зависимости от контекста некоторые из них могут быть разрешены и не должны быть закодированы
reserved_symbols_allowed = "абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ"
    For i =  1  To Len(reserved_symbols_allowed)
        ascii_map(Asc(Mid$(reserved_symbols_allowed, i,  1 ))) = Mid$(reserved_symbols_allowed, i,  1 )
          Next i
  
    ' Все остальные символы
    For i =  0  To  191 
        If i <  16  Then
            ascii_map(i) = "%0" & Hex$(i)
        Else
            If Len(ascii_map(i)) =  0  Then ascii_map(i) = "%" & Hex$(i)
        End If
    Next i
    flagTableInited = True
End If

For i =  1  To Len(plain_text)
    ts = ts & ascii_map(Asc(Mid$(plain_text, i,  1 )))
Next i

URLEncode_Ascii = ts

End Function
Функцию писал не я, я только ее немного редактировал для своих нужд. Сейчас она работает нормально, но для 200 кБ строку обрабатывает около минуты с лишним. Я долго искал нужные функции, но пока нашел только эту. И то она медленно работает, как получается.
Может быть, кто-то знает более эффективную аналогичную функцию или как ускорить эту?
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36573144
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
motorway,

Ну, во-первых, ByVal скорее всего лучше поменять на ByRef
Переприсвоение URLEncode_Ascii = ts тоже лишнее, можно сразу работать с URLEncode_Ascii.

Во-вторых, фактически рабочая часть алгоритма:
Код: plaintext
1.
2.
For i =  1  To Len(plain_text)
    ts = ts & ascii_map(Asc(Mid$(plain_text, i,  1 )))
Next i

Все тот же класс Concat, уже сосватанный вам Antonariy-ем, вполне решит проблему скорости, доведя ее до пары секунд, я думаю.
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36573150
motorway
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что ж, если уважаемый Antonariy сможет мне помочь, я буду благодарен. Для переделки функции под тот класс нужна твердая рука, а у меня опять что-то пульс зашкаливает (~102). Не подумайте, что я нахлебничаю, просто действительно сегодня практически нулевая работоспособность.
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36573154
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет уж - нахлебничаете. Ибо для переделки твердой руки не нужно (если, конечно, вы рассматривали тот пример Antonary и он не зря его вам писал)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
Public Function URLEncode_Ascii(ByRef plain_text As String) As String
'кодирует буквы для передачи на сервер
Dim ts As New Concat
Dim i As Long, cur_char As Byte
Dim reserved_symbols_allowed As String, unreserved_symbols As String
Static flagTableInited As Boolean
Static ascii_map( 0  To  255 ) As String

If Not flagTableInited Then
    ' Незарезервированные символы.
    ' Символы допустимые в URL
    unreserved_symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ"
    For i =  1  To Len(unreserved_symbols)
        ascii_map(Asc(Mid$(unreserved_symbols, i,  1 ))) = Mid$(unreserved_symbols, i,  1 )
    Next i
    ' Зарезервированные символы: !*'();:@&=+$,/?%#[] и пробел
    ' Спецсимволы которые не должны появляться в URI.
    ' Но в зависимости от контекста некоторые из них могут быть разрешены и не должны быть закодированы
reserved_symbols_allowed = "абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ"
    For i =  1  To Len(reserved_symbols_allowed)
        ascii_map(Asc(Mid$(reserved_symbols_allowed, i,  1 ))) = Mid$(reserved_symbols_allowed, i,  1 )
          Next i
  
    ' Все остальные символы
    For i =  0  To  191 
        If i <  16  Then
            ascii_map(i) = "%0" & Hex$(i)
        Else
            If Len(ascii_map(i)) =  0  Then ascii_map(i) = "%" & Hex$(i)
        End If
    Next i
    flagTableInited = True
End If

For i =  1  To Len(plain_text)
    ts.Append ascii_map(Asc(Mid$(plain_text, i,  1 )))
Next i

URLEncode_Ascii = ts.Result
ts.Clear: Set ts = Nothing

End Function
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36573155
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
П.С. Не проверял и не тестировал скорость
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36575642
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
motorway,

Как там у вас? Внедрили функцию? Просто очень интересно, насколько правильную оценку времени я дал :)
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36575815
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: Shocker.Pro
> Как там у вас? Внедрили функцию? Просто очень интересно, насколько правильную оценку времени я дал :)

Буквально на выходных самому понадобилась такая функция,
все что не находил не подошло
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
Option Explicit

Private Declare Function MultiByteToWideChar Lib "kernel32.dll" (ByVal CodePage As Long, _
    ByVal dwFlags As Long, ByVal lpMultiByteStr As String, ByVal cchMultiByte As Long, _
    ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" (ByVal CodePage As Long, _
    ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, _
    ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, _
    ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long

Public Function EncodeUTF8(strSrc As String) As String
    Dim nLen As Long
    Dim strDst As String
    Dim strRet As String
    Dim nRet As Long
    Dim p As Long

    nLen = Len(strSrc)
    strDst = String(nLen *  2 , Chr( 0 ))
    strRet = String(nLen *  2 , Chr( 0 ))
    p = StrPtr(strDst)
    nRet = MultiByteToWideChar( 1251 , &H1, strSrc, nLen, p, nLen)
    nRet = WideCharToMultiByte( 65001 ,  0 , p, nRet, StrPtr(strRet), nLen *  2 , ByVal  0 ,  0 )
    EncodeUTF8 = Left$(StrConv(strRet, vbUnicode), nRet)
End Function

Function UTF8_16(s)
    UTF8_16 = ""
    Dim i, j, j2, ch, k1, k2, k3, m
    i =  1 
    Do While i <= Len(s)
        ch = Mid(s, i,  1 )
        j = CLng(Asc(ch))
        If j >=  128  Then
            If j <  224  Then
                '2 байта
                k1 = j Mod  32 
                i = i +  1 
                ch = Mid(s, i,  1 )
                j2 = CLng(Asc(ch))
                k2 = j2 Mod  64 
                'ChrW - символ по UTF-16 значению
                UTF8_16 = UTF8_16 & ChrW(k2 + k1 *  64 )
            Else
                '3 байта
                k1 = j Mod  16 
                i = i +  1 
                ch = Mid(s, i,  1 )
                j2 = CLng(Asc(ch))
                k2 = j2 Mod  64 
                i = i +  1 
                ch = Mid(s, i,  1 )
                j2 = CLng(Asc(ch))
                k3 = j2 Mod  64 
                UTF8_16 = UTF8_16 & ChrW(k3 + (k2 + k1 *  64 ) *  64 )
            End If
        Else
            UTF8_16 = UTF8_16 & ch
        End If
        i = i +  1 
    Loop
End Function


'/// Функция кодирования недопустимых символов в URL.
    Public Function EncodeURIcomponent(SourceString)
        Dim i, C, Out
        For i =  1  To Len(SourceString)
          C = Asc(Mid(SourceString, i,  1 ))
          '/// Пробелы заменяем на плюс
          If C =  32  Then
            EncodeURIcomponent = EncodeURIcomponent + "+"
            '/// Запрещённые символы заменяем на "%" и HEX значение от кода символа
          ElseIf (C <  48  Or C >  126 ) Or (C >  56  And C <=  64 ) Then
            EncodeURIcomponent = EncodeURIcomponent + "%" + Hex(C)
          Else
          '/// Разрещённые символы добавляем как есть
            EncodeURIcomponent = EncodeURIcomponent + Chr(C)
          End If
        Next
    End Function
Sub xfh()
Dim i As Long, s As String, s1 As String, s2 As String
s = "Днепропетровск,Карла Маркса,35"
s2 = EncodeUTF8(s)
For i =  1  To Len(s)
    If Asc(Mid(s, i,  1 )) >  127  Then
        s1 = s1 & "%" & CStr(Hex(Asc((Mid(s2, i,  1 )))))
    Else
        s1 = s1 & Mid(s, i,  1 )
    End If
Next i
Debug.Print s1
s1 = URLEncode(s)
End Sub

 Function URLEncode(Data)
        Dim CharPosition, CharCode
        For CharPosition =  1  To Len(Data)
            CharCode = Asc(Mid(Data, CharPosition,  1 ))
            If CharCode =  32  Then
                URLEncode = URLEncode + "%20"
            ElseIf (CharCode <  48  Or CharCode >  126 ) Or (CharCode >  56  And CharCode <=  64 ) Then
                URLEncode = URLEncode + "%" + Right("0" & Hex(CharCode),  2 )
            Else
                URLEncode = URLEncode + Chr(CharCode)
            End If
        Next
    End Function

Sub dr()
Dim ie As Object, r As Worksheet, arr() As String
Dim MyStr As String
Dim i As Long
Set r = ThisWorkbook.Sheets("Kiev")
Set ie = CreateObject("InternetExplorer.Application")
For i =  1  To  494 
    'ie.Navigate 
"http://maps.google.com/maps/geo?q=%D0%94%D0%BD%D0%B5%D0%BF%D1%80%D0%BE%D0%BF%D0%B5%D1%82%D1%80%D0%BE%D0%B2%D1%81%D0%BA,%D0%9A%D0%B0%D1%80%D0%BB%D0%B0%20%D0%9C%D0%B0%D1%80%D0%BA%D1%81%D0%B0,35&output=csv"
    ie.Navigate "http://maps.google.com/maps/geo?q=" & r.Cells(i,  9 ).Value & "&output=csv"
    While ie.busy
      DoEvents
    Wend
    'MyStr = ie.Document.body.innerHTML
'    Debug.Print ie.document.body.innertext
    arr = Split(ie.document.body.innertext, ",")
    r.Cells(i,  10 ).Value = arr( 0 )
    r.Cells(i,  11 ).Value = arr( 1 )
    r.Cells(i,  12 ).Value = arr( 2 )
    r.Cells(i,  13 ).Value = arr( 3 )
Next i
Set r = ThisWorkbook.Sheets("Ukraine")
For i =  1  To  2071 
    'ie.Navigate 
"http://maps.google.com/maps/geo?q=%D0%94%D0%BD%D0%B5%D0%BF%D1%80%D0%BE%D0%BF%D0%B5%D1%82%D1%80%D0%BE%D0%B2%D1%81%D0%BA,%D0%A7%D0%BA%D0%B0%D0%BB%D0%BE%D0%B2%D0%B0,27&output=csv"
    ie.Navigate "http://maps.google.com/maps/geo?q=" & r.Cells(i,  9 ).Value & "&output=csv"
    While ie.busy
      DoEvents
    Wend
    'MyStr = ie.Document.body.innerHTML
'    Debug.Print ie.document.body.innertext
    arr = Split(ie.document.body.innertext, ",")
    r.Cells(i,  10 ).Value = arr( 0 )
    r.Cells(i,  11 ).Value = arr( 1 )
    r.Cells(i,  12 ).Value = arr( 2 )
    r.Cells(i,  13 ).Value = arr( 3 )
Next i

Set r = Nothing
ie.Quit
Set ie = Nothing
End Sub
, в результате выручил обыкновенный Жаба-скрипт:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var oEx = new ActiveXObject("Excel.Application");
oEx.Visible = true
var oB = oEx.workbooks.Open("K:\\atm_jan10_cl.xls");
var oSh = oB.sheets("Kiev");
for(i =  1 ; i <=  494 ; i++) {
 s = oSh.Cells(i,  2 ).Text + ", " + oSh.Cells(i,  4 ).Text;
 oSh.Cells(i,  9 ).Value = encodeURI(s);
}
WScript.Echo("Ok Kiev");
oSh = oB.sheets("Ukraine");
for(i =  1 ; i <=  2071 ; i++) {
 s = oSh.Cells(i,  3 ).Text + ", " + oSh.Cells(i,  4 ).Text;
 oSh.Cells(i,  9 ).Value = encodeURI(s);
}
WScript.Echo("Ok Ukraine");
который пришлось наваять по мотивам МСДН

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Проблема с функцией UrlEncode
    #36577636
motorway
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Promotorway,

Как там у вас? Внедрили функцию? Просто очень интересно, насколько правильную оценку времени я дал :)
Только сейчас удалось проверить. Да, время сократилось сильно - до <~1 сек. Спасибо!
На другие глюки пока не тестировал, если там все аналогично, думаю, их должно не быть.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Проблема с функцией UrlEncode
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]