А всё же интересно как заставить wininet работать с русскими символами. Повторюсь вот статья как это сделать на С++, но как сюда применить ума не приложу(((
кстати sokol92 примного Вам благодарен за включение головы, aka помощь, в вопросе!
itinich написал: понять бы что здесь говорят и как это применить...
Говорят о том, что упомянутые выше Windows API не поддерживают кодировку utf-8, которая сейчас используется на подавляющем большинстве серверов.
Посмотрите на возможность использования утилиты ftp (входит в состав Windows). Ей можно передать в параметрах файл в кодировке utf-8, содержащий нужные команды. Утилиту можно вызвать из Excel.
Альтернатива - curl (входит в текущую версию Windows и может устанавливаться на предыдущие версии). Эта программа всё умеет делать.Ка
Вы прям меня прочитали удалённо)))) Значит точно верное решение раз двум людям не сговариваясь пришло в голову)
В общем уважаемые форумчане в итоге как обычно всё через известное место))) Макрос делает следующее: - создаёт в %AppData% скрытый каталог - создаёт там батник и скрипт работы стандартной команды windows ftp - запускает батник - удаляет за собой скрытый каталог с содержимым Зато работает с русскими символами и пробелами в именах))) А ещё возможно и не требует адаптации к различным версиям ОС и офис И ещё обнаруженный нюанс - FileZilla Server не поддерживает команду mput *.* (ну это так на будущее, мало ли кому-то пригодится)
Скрытый текст
Код
Sub Upload2FTP()
On Error Resume Next
Set FSO = CreateObject("Scripting.FileSystemObject")
FSO.DeleteFolder (Environ("APPDATA") & "\2ftp")
FSO.CreateFolder (Environ("APPDATA") & "\2ftp")
FSO.GetFolder(Environ("APPDATA") & "\2ftp").Attributes = 2
ThisWorkbook.Save
On Error GoTo 0
Dim put2ftp As Object
Dim putscript As Object
Set put2ftp = FSO.CreateTextFile(Environ("APPDATA") & "\2ftp" & "\put2ftp.bat", True, False)
put2ftp.WriteLine "cd " & Environ("APPDATA") & "\2ftp"
put2ftp.WriteLine "ftp -s:putscript.txt"
put2ftp.WriteLine "cd.."
put2ftp.WriteLine "rd /s /q " & Environ("APPDATA") & "\2ftp"
Set put2ftp = Nothing
Set putscript = FSO.CreateTextFile(Environ("APPDATA") & "\2ftp" & "\putscript.txt", True, False)
putscript.WriteLine "prompt"
putscript.WriteLine "open 192.168.169.1"
putscript.WriteLine "test"
putscript.WriteLine "test"
putscript.WriteLine "MkDir Загрузка"
putscript.WriteLine "cd Загрузка"
putscript.WriteLine "binary"
putscript.WriteLine "put " & """" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & """"
putscript.WriteLine "Quit"
Set putscript = Nothing
CreateObject("WScript.Shell").Run Environ("APPDATA") & "\2ftp" & "\put2ftp.bat"
End Sub
а вот так реагирует уже другой FTPServer на попытку отработки скрипта с русскими символами: [I] May 28 16:45:53 pure-ftpd: (?@192.168.169.180) [INFO] test is now logged in [E] May 28 16:45:53 pure-ftpd: (test@192.168.169.180) [ERROR] Can't create directory: illegal byte sequence. [E] May 28 16:45:53 pure-ftpd: (test@192.168.169.180) [ERROR] Can't open that file: illegal byte sequence. [I] May 28 16:45:53 pure-ftpd: (test@192.168.169.180) [INFO] Logout.
причём судя по всему строка с именем передаваемого файла/создаваемого каталога в переменной формируется нормально (как собственно и без использования 'W', LongPtr и StrPtr). подозреваю ломается что-то дальше, на стадии передачи команды на FTPServer. включил ftp на роутере, такая же история (чтобы исключить возможные глюки FileZilla). понять бы что здесь говорят и как это применить...
'Open the Internet object
Private Declare PtrSafe Function InternetOpen _
Lib "wininet.dll" _
Alias "InternetOpenA" _
(ByVal sAgent As String, _
ByVal lAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Long) As Long
'Connect to the network
Private Declare PtrSafe Function InternetConnect _
Lib "wininet.dll" _
Alias "InternetConnectA" _
(ByVal hInternetSession As Long, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Long, _
ByVal lFlags As Long, _
ByVal lContext As Long) As Long
'Get a file using FTP
Private Declare PtrSafe Function FtpGetFile _
Lib "wininet.dll" _
Alias "FtpGetFileA" _
(ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
'Send a file using FTP
Private Declare PtrSafe Function FtpPutFile _
Lib "wininet.dll" _
Alias "FtpPutFileW" _
(ByVal hFtpSession As Long, _
ByVal lpszLocalFile As LongPtr, _
ByVal lpszRemoteFile As LongPtr, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
'Create directory using FTP
Private Declare PtrSafe Function FtpCreateDirectory _
Lib "wininet.dll" _
Alias "FtpCreateDirectoryW" _
(ByVal hFtpSession As Long, _
ByVal lpszDirectory As LongPtr) As Boolean
'Close the Internet object
Private Declare PtrSafe Function InternetCloseHandle _
Lib "wininet.dll" _
(ByVal hInet As Long) As Integer
Sub UploadFTP()
Dim ServerName As String
Dim UserName As String
Dim Password As String
Dim hostFile As String
Dim INet As Long
Dim INetConn As Long
Dim SuccessDir As Long
Dim SuccessFile As Long
Dim RetVal As Long
On Error Resume Next
ThisWorkbook.Save
CreateObject("Scripting.FileSystemObject").DeleteFolder (ThisWorkbook.Path & "\_2ftp_")
CreateObject("Scripting.FileSystemObject").CreateFolder (ThisWorkbook.Path & "\_2ftp_")
ThisWorkbook.SaveCopyAs (ThisWorkbook.Path & "\_2ftp_\" & ThisWorkbook.Name)
ServerName = "127.0.0.1"
UserName = "test"
Password = "test"
localFile = ThisWorkbook.Path & "\_2ftp_\" & ThisWorkbook.Name
hostFile = "//Тест/" & ThisWorkbook.Name
RetVal = False
INet = InternetOpen("---", 0, "", "", 0)
If INet > 0 Then
INetConn = InternetConnect(INet, ServerName, 0, UserName, Password, 1, 0, 0)
If INetConn > 0 Then
SuccessDir = FtpCreateDirectory(INetConn, StrPtr("Тест"))
SuccessFile = FtpPutFile(INetConn, StrPtr(localFile), StrPtr(hostFile), 0, 0)
RetVal = InternetCloseHandle(INetConn)
End If
RetVal = InternetCloseHandle(INet)
End If
CreateObject("Scripting.FileSystemObject").DeleteFolder (ThisWorkbook.Path & "\_2ftp_")
End Sub
'Open the Internet object
Private Declare PtrSafe Function InternetOpen _
Lib "wininet.dll" _
Alias "InternetOpenA" _
(ByVal sAgent As String, _
ByVal lAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Long) As Long
'Connect to the network
Private Declare PtrSafe Function InternetConnect _
Lib "wininet.dll" _
Alias "InternetConnectA" _
(ByVal hInternetSession As Long, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Long, _
ByVal lFlags As Long, _
ByVal lContext As Long) As Long
'Get a file using FTP
Private Declare PtrSafe Function FtpGetFile _
Lib "wininet.dll" _
Alias "FtpGetFileA" _
(ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
'Send a file using FTP
Private Declare PtrSafe Function FtpPutFile _
Lib "wininet.dll" _
Alias "FtpPutFileA" _
(ByVal hFtpSession As Long, _
ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
'Create directory using FTP
Private Declare PtrSafe Function FtpCreateDirectory _
Lib "wininet.dll" _
Alias "FtpCreateDirectoryA" _
(ByVal hFtpSession As Long, _
ByVal lpszDirectory As String) As Boolean
'Close the Internet object
Private Declare PtrSafe Function InternetCloseHandle _
Lib "wininet.dll" _
(ByVal hInet As Long) As Integer
Sub UploadFTP()
Dim hostFile As String
Dim INet As Long
Dim INetConn As Long
Dim Password As String
Dim RetVal As Long
Dim ServerName As String
Dim SuccessDir As Long
Dim SuccessFile As Long
Dim UserName As String
On Error Resume Next
ThisWorkbook.Save
CreateObject("Scripting.FileSystemObject").DeleteFolder (ThisWorkbook.Path & "\_2ftp_")
CreateObject("Scripting.FileSystemObject").CreateFolder (ThisWorkbook.Path & "\_2ftp_")
ThisWorkbook.SaveCopyAs (ThisWorkbook.Path & "\_2ftp_\" & ThisWorkbook.Name)
ServerName = "127.0.0.1"
UserName = "test"
Password = "test"
localFile = ThisWorkbook.Path & "\_2ftp_\" & ThisWorkbook.Name
hostFile = "//TestFolder/" & ThisWorkbook.Name
RetVal = False
INet = InternetOpen("---", 0, "", "", 0)
If INet > 0 Then
INetConn = InternetConnect(INet, ServerName, 0, UserName, Password, 1, 0, 0)
If INetConn > 0 Then
SuccessDir = FtpCreateDirectory(INetConn, "TestFolder")
SuccessFile = FtpPutFile(INetConn, localFile, hostFile, 0, 0)
RetVal = InternetCloseHandle(INetConn)
End If
RetVal = InternetCloseHandle(INet)
End If
CreateObject("Scripting.FileSystemObject").DeleteFolder (ThisWorkbook.Path & "\_2ftp_")
End Sub
А вот так нет:
Скрытый текст
Код
'Open the Internet object
Private Declare PtrSafe Function InternetOpen _
Lib "wininet.dll" _
Alias "InternetOpenA" _
(ByVal sAgent As String, _
ByVal lAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Long) As Long
'Connect to the network
Private Declare PtrSafe Function InternetConnect _
Lib "wininet.dll" _
Alias "InternetConnectA" _
(ByVal hInternetSession As Long, _
ByVal sServerName As String, _
ByVal nServerPort As Integer, _
ByVal sUsername As String, _
ByVal sPassword As String, _
ByVal lService As Long, _
ByVal lFlags As Long, _
ByVal lContext As Long) As Long
'Get a file using FTP
Private Declare PtrSafe Function FtpGetFile _
Lib "wininet.dll" _
Alias "FtpGetFileA" _
(ByVal hFtpSession As Long, _
ByVal lpszRemoteFile As String, _
ByVal lpszNewFile As String, _
ByVal fFailIfExists As Boolean, _
ByVal dwFlagsAndAttributes As Long, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
'Send a file using FTP
Private Declare PtrSafe Function FtpPutFile _
Lib "wininet.dll" _
Alias "FtpPutFileA" _
(ByVal hFtpSession As Long, _
ByVal lpszLocalFile As String, _
ByVal lpszRemoteFile As String, _
ByVal dwFlags As Long, _
ByVal dwContext As Long) As Boolean
'Create directory using FTP
Private Declare PtrSafe Function FtpCreateDirectory _
Lib "wininet.dll" _
Alias "FtpCreateDirectoryA" _
(ByVal hFtpSession As Long, _
ByVal lpszDirectory As String) As Boolean
'Close the Internet object
Private Declare PtrSafe Function InternetCloseHandle _
Lib "wininet.dll" _
(ByVal hInet As Long) As Integer
Sub UploadFTP()
Dim hostFile As String
Dim INet As Long
Dim INetConn As Long
Dim Password As String
Dim RetVal As Long
Dim ServerName As String
Dim SuccessDir As Long
Dim SuccessFile As Long
Dim UserName As String
On Error Resume Next
ThisWorkbook.Save
CreateObject("Scripting.FileSystemObject").DeleteFolder (ThisWorkbook.Path & "\_2ftp_")
CreateObject("Scripting.FileSystemObject").CreateFolder (ThisWorkbook.Path & "\_2ftp_")
ThisWorkbook.SaveCopyAs (ThisWorkbook.Path & "\_2ftp_\" & ThisWorkbook.Name)
ServerName = "127.0.0.1"
UserName = "test"
Password = "test"
localFile = ThisWorkbook.Path & "\_2ftp_\" & ThisWorkbook.Name
hostFile = "//ТестовыйКаталог/" & ThisWorkbook.Name
RetVal = False
INet = InternetOpen("---", 0, "", "", 0)
If INet > 0 Then
INetConn = InternetConnect(INet, ServerName, 0, UserName, Password, 1, 0, 0)
If INetConn > 0 Then
SuccessDir = FtpCreateDirectory(INetConn, "ТестовыйКаталог")
SuccessFile = FtpPutFile(INetConn, localFile, hostFile, 0, 0)
RetVal = InternetCloseHandle(INetConn)
End If
RetVal = InternetCloseHandle(INet)
End If
CreateObject("Scripting.FileSystemObject").DeleteFolder (ThisWorkbook.Path & "\_2ftp_")
End Sub
Во втором случае имя создаваемого каталога написано на русском.
Есть предположение что "собака порылась" в кодировках (ANSI / Unicode), но вот куда смотреть ума не приложу, помогите пожалуйста.
FTPServer это FileZilla, если к нему цепляться "руками" любым из клиентов, каталоги с русскими символами работают норм.
Такая же проблема если файл имеет русские символы в имени.
написал: источник Понравился тем, что нет ни подключения OCX ни ….
Скрытый текст
Код
[URL=#]?[/URL] 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 'Open the Internet object Private Declare Function InternetOpen _ Lib "wininet.dll" _ Alias "InternetOpenA" _ ( ByVal sAgent As String , _ ByVal lAccessType As Long , _ ByVal sProxyName As String , _ ByVal sProxyBypass As String , _ ByVal lFlags As Long ) As Long 'Connect to the network Private Declare Function InternetConnect _ Lib "wininet.dll" _ Alias "InternetConnectA" _ ( ByVal hInternetSession As Long , _ ByVal sServerName As String , _ ByVal nServerPort As Integer , _ ByVal sUsername As String , _ ByVal sPassword As String , _ ByVal lService As Long , _ ByVal lFlags As Long , _ ByVal lContext As Long ) As Long 'Get a file using FTP Private Declare Function FtpGetFile _ Lib "wininet.dll" _ Alias "FtpGetFileA" _ ( ByVal hFtpSession As Long , _ ByVal lpszRemoteFile As String , _ ByVal lpszNewFile As String , _ ByVal fFailIfExists As Boolean , _ ByVal dwFlagsAndAttributes As Long , _ ByVal dwFlags As Long , _ ByVal dwContext As Long ) As Boolean 'Send a file using FTP Private Declare Function FtpPutFile _ Lib "wininet.dll" _ Alias "FtpPutFileA" _ ( ByVal hFtpSession As Long , _ ByVal lpszLocalFile As String , _ ByVal lpszRemoteFile As String , _ ByVal dwFlags As Long , _ ByVal dwContext As Long ) As Boolean 'Close the Internet object Private Declare Function InternetCloseHandle _ Lib "wininet.dll" _ ( ByVal hInet As Long ) As Integer Sub UploadFTP() Dim hostFile As String Dim INet As Long Dim INetConn As Long Dim Password As String Dim RetVal As Long Dim ServerName As String Dim Success As Long Dim UserName As String Const ASCII_TRANSFER = 1 Const BINARY_TRANSFER = 2 ServerName = ThisWorkbook.Sheets(1).Cells(1, 1) UserName = "UserName" Password = "Password" localFile = ThisWorkbook.Sheets(1).Cells(1, 2) ' "C:\TEMP\File.ext" hostFile = ThisWorkbook.Sheets(1).Cells(2, 2) ' "//Folder/Folder/File.ext" RetVal = False INet = InternetOpen( "MyFTP Control" , 1&, vbNullString, vbNullString, 0&) If INet > 0 Then INetConn = InternetConnect(INet, ServerName, 0&, UserName, Password, 1&, 0&, 0&) If INetConn > 0 Then Success = FtpPutFile(INetConn, localFile, hostFile, BINARY_TRANSFER, 0&) RetVal = InternetCloseHandle(INetConn) End If RetVal = InternetCloseHandle(INet) End If ' If Success <> 0 Then ' MsgBox ("Upload process completed") ' Else ' MsgBox "FTP File Error!" ' End If End Sub
на гуглить конечно на гуглил, как правильно считать и даже на физическом примере посчитал (*подсказка) но вот почему именно так нужно считать всё равно осталось пока ещё загадкой
что касаемо примера №2 всё выглядит вот так: - из 100 учеников задание 1 выполнили 30 человек - это 30% от общего числа - далее для всех задания рассчитан процент выполнивших из общего кол-ва участвовавших - если посчитать процент общего кол-ва сдавших от общего числа сдававших, получается 37% - но если посчитать среднее значение отношения сдавших к сдававшим - получается иное значение
Это определённо разные понятия, но в данном случае вес всех чисел одинаков. Как Вы поняли что он разный? Возможно что-то не так описал? Тогда дополню: - есть число 1 оно имеет 2 значения, далее берём какой процент значения 2 есть в значении 1, и так далее для множества чисел, в данном случае для четырёх. - затем берём среднее значение этих отношений и получаем число выделенное зелёным при этом если считать отношение сумм значений 2 к сумме значений 1 получается иная цифра, почему?
Доброго вечерочку уважаемые форумчане и форумчанки! Никак не могу разобраться почему именно так происходит. Т.е. как именно правильно считать понимаю, но почему одно из двух чисел не верное не понимаю. Помогите пожалуйста разобраться в головоломке... Итак почему же красное и зелёное числа разные? ЗЫ: на скриншоте приведено 2 примера с формулами, оба идентичные, просто кому как удобнее для понимания.
Изменено: itinich - 24.03.2022 21:04:47(добавление описания изображения)
Dyroff, спасибо большое это именно то что мне нужно было - сводная таблица сделанная по промежуточной. Во вложении окончательный вариант для дальнейшего наполнения.
здравствуйте уважаемые форумчане! никак не могу сообразить как получить конечный результат и прошу помощи.
суть задачи такая: есть таблица в файле excel по продажам (пример исходник.jpg), в этом же файле на основе первоначальной нужно получить результирующую таблицу (пример результат.jpg). желательно всё сделать стандартными формулами, без vba и макросов, если возможно.
в файле приведено то что уже наработано: изначальная таблица разделена на несколько по видам продуктов вопрос как их совместить в одну?