26

Re: VBS: хитрости/особенности

Вроде бы да

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

27

Re: VBS: хитрости/особенности

Я бы сказал, что Me ссылается на экземпляр объекта.

( 2 * b ) || ! ( 2 * b )

28 (изменено: Rumata, 2011-10-09 10:34:08)

Re: VBS: хитрости/особенности

Вроде бы тематически подходит.

Я недавно решил перевести небольшой фрагмент кода работы с javascript на vbscript. С сожалением обнаружил, что в Vbscript весьма неудобные функции для работы с датой. Например:

1. получить количество дней в текущем месяце


var days = new Date(2011, 9 + 1, 0).getDate();

на vbscript объемнее, но еще терпимо


N = Now
F = DateAdd("m", 1, N)
days = DateDiff("d", N, F)

2. получить день недели для последнего дня месяца


var lday = new Date(2011, 9 + 1, 0).getDay();

на vbscript "неуклюжий"


N = Now
F = DateAdd("m", 1, N)
F = DateAdd("d", -DatePart("d", F), F)

lday = DatePart("w", F)

Подскажите, пожалуйста. Это такое положение вещей или я просто плохо искал?

( 2 * b ) || ! ( 2 * b )

29

Re: VBS: хитрости/особенности

Rumata пишет:

... обнаружил, что в Vbscript весьма неудобные функции для работы с датой...

А мне нравятся средства VBS:

'1. получить количество дней в текущем месяце
DateSerial(Year(Date), Month(Date) + 1 , 1) - DateSerial(Year(Date), Month(Date), 1)

'2. получить день недели для последнего дня текущего месяца
Weekday(DateSerial(Year(Date), Month(Date) + 1, 0), 2) 'первый день недели - понедельник

30

Re: VBS: хитрости/особенности

Бррр...

WScript.Echo Now
WScript.Echo Weekday(Now, vbUseSystemDayOfWeek)
WScript.Echo Weekday(Now, vbSunday)
WScript.Echo Weekday(Now, vbMonday)

Результат...

C:\>cscript z.vbs
Microsoft (R) Windows Script Host Version 5.7
Copyright (C) Microsoft Corporation. All rights reserved.

10.10.2011 14:48:16
1
2
1

Ой как не информативно. Что есть 1 и 2? 1 - понедельник или воскресенье?

Здесь Weekday Function четко сказано, что

The Weekday function can return any of these values:
vbSunday 1 Sunday
vbMonday 2 Monday
...

( 2 * b ) || ! ( 2 * b )

31

Re: VBS: хитрости/особенности

А-а-а... У них на МСДНе неверная информация. Понял как надо интерпретировать возвращаемую информацию. Weekday возвращает порядковый номер дня недели для данной даты, если бы отсчет начинался с определенного дня в неделе. То есть, если отсчет начинается с воскресенья (1), то понедельник - второй день, если с понедельника (2), то понедельник - день первый, и т.д.

( 2 * b ) || ! ( 2 * b )

32

Re: VBS: хитрости/особенности

Как цитировал когда-то коллега Xameleon — «если звёзды зажигают…» Благодаря данной теме, я сумел решить старую больную проблему, а именно: определить внутри обработки событий объекта «WshRemote» конкретный экземпляр объекта, вызвавший данное событие, и получить к нему доступ. Сие стало доступным, благодаря данной теме и коллегам Xameleon и Rumata (наподобие VBS/WMI: Многопоточный WshController с ограничением длины очереди, но проще).

Remote.vbs, имитация случайного времени исполнения удалённого скрипта:

Option Explicit

Dim lngTime

Randomize Timer

lngTime = Rnd() * 10 * 1000

WScript.Sleep lngTime

WScript.Quit 0

Local.vbs, пока без организации очереди, без реальной удалённой работы — только демонстрация концепции:

Option Explicit

Dim objDictionary

Dim objWshController
Dim objWshRemote

Dim i
Dim intKey


Set objDictionary    = WScript.CreateObject("Scripting.Dictionary")
Set objWshController = WScript.CreateObject("WSHController")

For i = 1 To 20
	Set objWshRemote = objWshController.CreateScript("""C:\Мои проекты\WshController\Remote.vbs""")
	WScript.ConnectObject objWshRemote, "Remote_"
	
	objDictionary.Add i, objWshRemote
Next


For Each intKey In objDictionary.Keys
	objDictionary.Item(intKey).Execute
Next

Do
	WScript.Sleep 100
Loop Until objDictionary.Count = 0

Set objWshController = Nothing
Set objDictionary    = Nothing

WScript.Quit 0
'=============================================================================

'=============================================================================
Sub Remote_Error
	Dim objWshError
	
	Set objWshError = Me.Error
	WScript.Echo "Error " & objWshError.Number & " - Line: " & objWshError.Line & ", Char: " & objWshError.Character & vbCrLf & "Description: " & objWshError.Description
End Sub
'=============================================================================

'=============================================================================
Sub Remote_Start
	Dim intKey
	
	For Each intKey In objDictionary.Keys
		If Me Is objDictionary.Item(intKey) Then
			WScript.Echo "Start", intKey
		End If
	Next
End Sub
'=============================================================================

'=============================================================================
Sub Remote_End
	Dim intKey
	
	For Each intKey In objDictionary.Keys
		If Me Is objDictionary.Item(intKey) Then
			WScript.Echo "End", intKey
			
			WScript.DisconnectObject objDictionary.Item(intKey)
			Set objDictionary.Item(intKey) = Nothing
			
			objDictionary.Remove intKey
		End If
	Next
End Sub
'=============================================================================

33

Re: VBS: хитрости/особенности

Блин, дошло !!!
Не сразу, но дошло....  фишка в me
Вообще прикольно !!!
alexii - МОЗГ !!!
Признаю - это лучше моего того варианта !!!
Это настоящая многопоточность WSHController !!!

Времени не хватает... :-(

34

Re: VBS: хитрости/особенности

Поправил в своём предыдущем посте все позабытые на радостях «theError» на «objWshError».

35

Re: VBS: хитрости/особенности

OFF: smile Никогда бы не подумал, что это для кого то станет открытием. ) Наверное потому что слишком к этому привык. Повторюсь - ":D Поздравляю ! У каждого Колумба своя Америка )". Рад что у Вас получилось задуманное.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

36

Re: VBS: хитрости/особенности

Ссспасибо! smile Я действительно всегда предполагал, что Me — прерогатива больших VB-языков.

Xameleon пишет:

У каждого Колумба своя Америка

И это запомню wink.

37

Re: VBS: хитрости/особенности

2 alexii будет ли окончательный вариант реализации многопоточности в Вашем исполнении ?
(с предварительной асинхронной проверкой хостов пингами, ограничением длины очереди потоков , логированием успешности отработки и т.д. и т.п.)

Времени не хватает... :-(

38

Re: VBS: хитрости/особенности

Евген, в ближайшие пару месяцев я вряд ли найду время. И, как показывает опыт, где два месяца — там и четыре sad.

39

Re: VBS: хитрости/особенности

Всем доброго времени суток! Экспериментируя с execute(), я обнаружил возможность создавать функции, "вложенные" в функции - динамически объявлять процедуры и функции в области видимости переменных определенной процедуры или функции (метода, принадлежащего экземпляру класса). Правда, объявленная таким образом "локальная" функция не видит локальных переменных (переменных экземпляра класса), а обращается напрямую к глобальным переменным скрипта.

dim x
x = "global"
' вызов процедуры, объявляющей внутри себя процедуру
globalsub()
' после завершения процедуры объявленная в ней процедура более недоступна для вызова
' localsub() ' ошибка - несоответствие типа, в глобальном контексте процедура не появляется

sub globalsub()
    dim x
    x = "local" ' локально объявленная процедура не видит локально объявленную переменную
    execute _
        "sub localsub()" & vbcrlf & _
            "msgbox ""localsub message""" & vbcrlf & _
            "msgbox ""x = "" & x" & vbcrlf & _
        "end sub"
    localsub()
end sub

Подобным образом могут быть динамически объявлены классы в области видимости переменных определенной процедуры, функции, метода экземпляра класса, и в области видимости экземпляра класса.

' получение экземпляра класса, объявленного внутри функции
set objsourceless = newobj()
msgbox typename(objsourceless)
' после завершения функции объявленный в ней класс более недоступен для создания новых экземпляров
' set objtest = new clslocal ' ошибка - класс не определен, в глобальном контексте класс не появляется
' объявление класса внутри экземпляра класса, объявленного внутри функции
objsourceless.executestatement _
    "class clsadditional" & vbcrlf & _
        "public default sub run()" & vbcrlf & _
            "msgbox ""additional class message""" & vbcrlf & _
        "end sub" & vbcrlf & _
    "end class"
' получение экземпляра класса, объявленного внутри экземпляра класса, объявленного внутри функции
set objadditional = objsourceless.getinstance("clsadditional")
msgbox typename(objadditional)
objadditional()

function newobj()
    ' создание класса в области видимости функции
    execute _
        "class clslocal" & vbcrlf & _
            "public sub executestatement(statement)" & vbcrlf & _
                "executeglobal statement" & vbcrlf & _
            "end sub" & vbcrlf & _
            "public function getinstance(clsname)" & vbcrlf & _
                "set getinstance = eval(""new "" & clsname)" & vbcrlf & _
            "end function" & vbcrlf & _
        "end class"
    ' создание экземпляра класса
    set newobj = new clslocal
end function

А теперь о главном. Практической пользы в данной возможности я углядеть так и не сумел. big_smile

Щт Уккщк Куыгьу Туче

40

Re: VBS: хитрости/особенности

omegastripes, для меня неожиданно и крайне интересно. ) Возьму на заметку. Мне такой "фокус" был нужен, когда хотел ссылку на onreadystatechange зацепить процедуру внутри класса. Сейчас попробую.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

41

Re: VBS: хитрости/особенности

Продолжая тему VBScript: создание пользовательского объекта, можно использовать еще один вариант. Создание пользовательского объекта как экземпляра локально объявленного класса позволит не засорять глобальное пространство скрипта:

strmytypename = "customobject" ' тип объекта
arrmykeys = array("property1", "property2") ' массив с названиями свойств объека
arrmyvalues = array("value1", createobject("scripting.dictionary")) ' массив со значениями свойств
' создание объекта
set objmy = getmyobj(strmytypename, arrmykeys, arrmyvalues)
' проверка
msgbox typename(objmy)
msgbox objmy.property1
msgbox typename(objmy.property2)

function getmyobj(strtypename, arrkeys, arrvalues)
    dim i
    execute "class " & strtypename & ": public " & join(arrkeys, ", ") & ": end class: set getmyobj = new " & strtypename
    for i = 0 to ubound(arrkeys)
        if isobject(arrvalues(i)) then
            execute "set getmyobj." & arrkeys(i) & " = arrvalues(i)"
        else
            execute "getmyobj." & arrkeys(i) & " = arrvalues(i)"
        end if
    next
end function
Щт Уккщк Куыгьу Туче

42

Re: VBS: хитрости/особенности

И еще один момент, касающийся execute, в дополнение к посту #39.
В то время, как вызов execute внутри процедуры или функции (или внутри метода экземпляра класса) создаёт процедуры, функции и классы локально, простое присвоение значения еще не объявленной переменной приводит к созданию переменной с этим значением в глобальном пространстве скрипта. Такое поведение я ожидал от executeglobal, но никак не от execute.. mad При чем данное присвоение даже не вызовет ошибку "переменная не определена" при наличии option explicit в первой строке скрипта - ошибка появится лишь в том случае, если инструкцию option explicit поставить вначале строки, выполняемой execute.

Щт Уккщк Куыгьу Туче

43

Re: VBS: хитрости/особенности

Давно (уже года 2-3, наверно) хотел спросить по поводу этой фичи, предложенной Rumata.
Есть возможность применять при нескольких параметрах?

44

Re: VBS: хитрости/особенности

Flasher,

Наверное можно так:


Call Test("Text1", vbInformation, "Title1")("Text2", vbExclamation, "Title2")

Function Test(Prompt, Buttons, Title)
	MsgBox Prompt, Buttons, Title
	Set Test = GetRef("Test")
End Function
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

45

Re: VBS: хитрости/особенности

Xameleon
Оно! Спасибо! Плюс это решает проблему обрыва и необходимости повтора последнего вызова в цепочке.
И, полагаю, имеет смысл в ряде случаев применять CPS вместо цикла в цикле. Нашёл по теме на русском.

P.S.: Это ж надо было столько прождать, чтобы узнать, что всё уткнётся в Call. Столько бы места и времени сэкономил...

46

Re: VBS: хитрости/особенности

Flasher, Вам попалась задача, где цепочки вызовов в VBS пригодились?

( 2 * b ) || ! ( 2 * b )

47

Re: VBS: хитрости/особенности

Rumata, да, хватало таких задач.

48

Re: VBS: хитрости/особенности

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

( 2 * b ) || ! ( 2 * b )

49

Re: VBS: хитрости/особенности

Покажу на простом примере:

' Есть некая дата в неподходящем формате (файла, например)
FDate = "5/5/5 5:5:5"

Dy = Day(FDate)  : Mh = Month(FDate)  : Yr = Year(FDate)
Hr = Hour(FDate) : Mn = Minute(FDate) : Sc = Second(FDate)

' Запишем в переменную дату 1-го преобразования
NDate = ReDate(FDate)

' Вызовем функцию 2-го преобразования
Call AddNull(Dy)(Mh)(Hr)(Mn)(Sc)

' Покажем разницу
MsgBox  "До преобразований:" & vbTab & FDate &_
vbCr & "1-е преобразование:" & vbTab & NDate &_
vbCr & "2-е преобразование:" & vbTab & ReDate(FDate)

Function AddNull(DateT)
  DateT = Right("0" & DateT, 2)
  Set AddNull = GetRef("AddNull")
End Function

Function ReDate(FDate)
  ReDate = Dy & "." & Mh & "." & Yr & " " & Hr & ":" & Mn & ":" & Sc
End Function

50

Re: VBS: хитрости/особенности

Flasher

Оно! Спасибо! Плюс это решает проблему обрыва и необходимости повтора последнего вызова в цепочке.

Wow. smile Да не за что. Рад, что пригодилось. Посмотрел Ваш пример, но пока что не понял почему нельзя его было реализовать по аналогии с этой темой - VBS: Abby Finereader Bank 6.0. Выгрузка даты в dbf в формате ggggmmdd ?

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !