Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2010, 00:09   #1
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
По умолчанию Проблема с функцией UrlEncode

Всем доброго дня.
В очередной раз у меня появилась проблема, связанная с быстродействием макроса при обработке большого количества данных. Из Эксела на сервер посылается строка, но чтобы все символы правильно доходили, ее нужно закодировать. Это делается с помощью следующей функции:
Код:
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 кБ строку обрабатывает около минуты с лишним. Я долго искал нужные функции, но пока нашел только эту. И то она медленно работает, как получается.
Может быть, кто-то знает более эффективную аналогичную функцию или как ускорить эту?
motorway вне форума Ответить с цитированием
Старый 12.04.2010, 00:48   #2
EducatedFool
Программист VBA
СуперМодератор
 
Аватар для EducatedFool
 
Регистрация: 13.07.2008
Сообщений: 6,856
По умолчанию

Вопрос немного не по теме:
А зачем сначала выгружать содержимое ячеек в текстовый файл, а потом кодировать этот файл и отправлять на сервер?
Для чего всё это? Что надо получить в итоге?

Я не утверждаю, что всё это неправильно, но, может, есть какой-то другой, намного более простой, метод...
Пока что для меня остаётся загадкой, чего вы пытаетесь добиться своей программой.
EducatedFool вне форума Ответить с цитированием
Старый 12.04.2010, 01:49   #3
motorway
Участник клуба
 
Регистрация: 28.06.2009
Сообщений: 1,950
По умолчанию

Текстовый файл нужен для сохранения промежуточных результатов. На сервер отправляется не файл, а просто строка.
Посылаются исходные данные для вычислений. В итоге приходят результаты вычислений. То есть, всё работает как веб-сервис, но с помощью Эксела
motorway вне форума Ответить с цитированием
Старый 12.04.2010, 10:49   #4
Aent
Форумчанин
 
Аватар для Aent
 
Регистрация: 17.07.2009
Сообщений: 519
По умолчанию

У меня то же, как и у EducatedFool, большие сомнения в правильности концепции.
При таких объёмах передаваемых данных IMHO лучше использовать двоичный обмен. Впрочем, тут всё зависит от сервера.
Тем не менее, попробуйте в вашем макросе заменить
Код:
For i = 1 To Len(plain_text)
    ts = ts & ascii_map(Asc(Mid$(plain_text, i, 1)))
Next i
URLEncode_Ascii = ts
на
Код:
Dim j as long
Dim ss as string 
ts = string(Len(plain_text)*3,vbNullChar)
j = 1
for i = 1 to Len(plain_text)
     ss=ascii_map(Asc(Mid$(plain_text, i, 1)))
     if left$(ss,1) = "%" then
          Mid$(ts,j,3) = ss
          j = j+3
     else
          Mid$(ts,j,1) = ss
          j =j+1
     end if
next i
URLEncode_Ascii = Left$(ts,j-1)
Приведённый код можно ещё ускорить добавив в макрос массив статический массив Boolean c признаком нужна ли замена символа.

Последний раз редактировалось Aent; 12.04.2010 в 15:33.
Aent вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с функцией SUM Sneginka87 БД в Delphi 8 27.02.2010 02:34
Проблема с функцией Replace... Oooleg Microsoft Office Excel 7 02.09.2009 05:22
Функция UrlEncode - как подключить motorway Microsoft Office Excel 0 04.07.2009 19:27
Проблема с функцией замены... dast Microsoft Office Excel 6 09.10.2008 20:30