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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
'Стандартизация значений по строкам
'(другие названия: стандартизация наблюдений, стандартизация переменных по строкам)

'Начало описания
'Скрипт проводит стандартизацию значений по строкам.
'Создаётся диалоговое окно, позволяющее пользователю указать (по крайней мере, три)
'переменных для стандартизации по строкам. Принцип стандартизации: если, например,
'выделено 4 переменных (скажем, ответы на вопросы анкеты), скрипт стандартизирует значение
'каждого ответа на основе среднего значения и стандартного отклонения данного (i-го) наблюдения
'по всем четырём переменным (т.е. score1i = (score1i - СРЕДНЕЕ из (score1i, score2i, score3i, score4i))/СТД ОТКЛ. из (score1i, score2i, score3i, score4i).
'Конец описания
Option Explicit

'Объявление констант уровня скрипта
Const cDLGTITLE As String = "Стандартизация значений по строкам"
Const cOK As String = "Да"
Const cCANCEL As String = "Отмена"
Const cROOTNAME As String = "Начальная часть имени новых переменных:"
Const cSELVARS As String = "Выбранные переменные"
Const cVARROOT As String = "VAR"
Const cROOTMSG As String = "Укажите начальную часть имени новых переменных."
Const cSCRIPTNAME As String = "Стандартизация значений по строкам"
Const cSELMSG As String = "Укажите, по крайней мере, 3 переменные."


Public strNotSelVar() As String
Public strSelVar() As String
Public strListOfVars() As String
Public bolSelected() As Boolean
Public intArrayIndex() As Integer
Public strFilePath As String

Sub Main

	BuildDialog

End Sub

Sub RunJob
'Назначение: запускает синтаксис, который стандартизирует значения по строкам
'Предположения: не заданы
'Результат: создание новых переменных со стандартизированными значениями
'Входные данные: не заданы
'Возвращаемые значения: не заданы

Dim strCmd1 As String
Dim strCmd2 As String
Dim strCmd3 As String
Dim strCmd4 As String
Dim intSelVarIndex As Integer

	strCmd1 = "COMPUTE #MEAN_ = MEAN("
	strCmd2  = "COMPUTE #SD_ = SD("
	For intSelVarIndex = 0 To UBound(strSelVar) 
    	If intSelVarIndex < UBound(strSelVar)  Then
        	strCmd1 = strCmd1 & strSelVar(intSelVarIndex) & ","
        	strCmd2  = strCmd2  & strSelVar(intSelVarIndex) & ","
    	ElseIf intSelVarIndex = UBound(strSelVar)  Then
        	strCmd1 = strCmd1 & strSelVar(intSelVarIndex) & ")."
        	strCmd2  = strCmd2  & strSelVar(intSelVarIndex) & ")."
    	End If
	Next
	
	objSpssApp.ExecuteCommands strCmd1, False
	objSpssApp.ExecuteCommands strCmd2, False
	For intSelVarIndex = 0 To UBound(strSelVar) 
 		strCmd3 = "COMPUTE " & DlgText("txtRootName") & intSelVarIndex+1 & " = (" & strSelVar(intSelVarIndex) & "- #MEAN_) / #SD_."
 		objSpssApp.ExecuteCommands strCmd3, False
	Next

	strCmd4 = "EXECUTE."
	objSpssApp.ExecuteCommands strCmd4, False
    
End Sub

Sub BuildDialog
'Назначение: создаёт и выводит диалог, который позволяет пользователю выбрать переменные,
' по которым будет осуществляться стандартизация
'Предположения: не заданы
'Результат: не задан
'Входные данные: не заданы
'Возвращаемые значения: не заданы

	ReDim strNotSelVar(0) As String
	ReDim strSelVar(0) As String

	Begin Dialog UserDialog 540,203,cDLGTITLE,.DialogMonitor
		ListBox 30,28,140,119,strNotSelVar(),.lstVarInFile
		ListBox 240,28,150,119,strSelVar(),.lstSelVar
		PushButton 430,14,90,21, cOK,.cmdRun
		PushButton 430,42,90,21, cCANCEL,.cmdCancel
		PushButton 190,77,30,21,">",.cmdMoveIt
		TextBox 290,161,100,21,.txtRootName
		Text 100,165,190,14, cROOTNAME,.Field7
		Text 240,14,140,14, cSELVARS,.lbl1
	End Dialog

	Dim dlg As UserDialog

	Dialog dlg
	
End Sub

Function DialogMonitor(strDialogItem As String, intAction As Integer, intSuppValue As Integer) As Boolean
'Назначение: Следит за возникающими событиями диалогового окна
'Предположения: не заданы
'Результат: не задан. Следит за событиями диалогового окна и вызывает процедуры-обработчики этих событий
'Входные значения: выбранный элемент управления (strDialogItem), выполненное действие (intAction),
'		 и дополнительное значение, возникающее для некоторых событий элементов управления (intSuppValue)
'Возвращаемые значения: ИСТИНА (TRUE), если диалог остаётся видимым; ЛОЖЬ (FALSE), если должен быть закрыт.

    Select Case intAction
	    Case 1 ' Инициализация диалогового окна
	    	DlgEnable "cmdCancel", True
	    	DlgEnable "cmdRun", True
	    	DlgText "txtRootName",  cVARROOT
	    	GetVarsFromFile		'Процедура, берущая переменную из файла и помещающая её в список в диалоговом окне
	    Case 2 ' Изменилось значение или нажата клавиша
	        Select Case strDialogItem
	        	Case "cmdRun"
	        		If DlgText("txtRootName") = "" Then
						MsgBox cROOTMSG, 48, cSCRIPTNAME
						DialogMonitor = True
					ElseIf UBound(strSelVar) < 2 Then
						MsgBox cSELMSG, 48, cSCRIPTNAME
						DialogMonitor = True
					Else
	        			Call RunJob
	        			DialogMonitor = False
	        		End If
	        	Case "cmdCancel"
	        		DialogMonitor = False
	        	Case "lstVarInFile"
	        		DlgText "cmdMoveIt", ">"
	        		DlgEnable "cmdMoveIt", True
	        		DialogMonitor = True
	        	Case "lstSelVar"
	        		DlgText "cmdMoveIt", "<"
	        		DialogMonitor = True
	        	Case "cmdMoveIt"
	        		If DlgText("cmdMoveIt") = ">" Then 	'добавить переменную в список выбранных переменных
	        			Call AddToSelList
	        		Else								'удалить переменную из списка выбранных переменных
	        			Call RemoveFromSelList
	        		End If
	        		DialogMonitor = True
	        End Select
	End Select
End Function

Sub AddToSelList()
'Назначение: изменяет статус переменной с не выбранной на выбранную
'Предположения: не заданы
'Результат: изменяет соответствующую запись в массиве bolSelected с ЛЖИ (FALSE) на ИСТИНУ (TRUE)
'Входные значения: не заданы
'Возвращаемые значения: не заданы

	Dim intSelIndex As Integer
	Dim i As Integer
	
	intSelIndex = DlgValue("lstVarInFile")
	'пробегаем по массиву intArrayIndex; если обнаруживаем, что переменная была выбрана,
	'изменяем её запись в массиве bolSelected на ИСТИНУ (TRUE)
	For i = 0 To UBound(intArrayIndex)
		If (intArrayIndex(i) = intSelIndex) And (bolSelected(i) = False) Then
			bolSelected(i) = True
			Exit For
		End If
	Next i
	Call PopulateLists	'Обновляет списки доступных и выбранных переменных в диалоговом окне

End Sub

Sub RemoveFromSelList()
'Назначение: изменяет статус переменной с выбранной на не выбранную
'Предположения: не заданы
'Результат: изменяет соответствующую запись в массиве bolSelected с ИСТИНЫ (TRUE) на ЛОЖЬ (FALSE)
'Входные значения: не заданы
'Возвращаемые значения: не заданы

	Dim intSelIndex As Integer
	Dim i As Integer
	
	intSelIndex = DlgValue("lstSelVar")
	'пробегаем по массиву intArrayIndex; если обнаруживаем, что переменная была удалена из списка выбранных,
	' изменяем её запись в массиве bolSelected на ЛОЖЬ (FALSE)
	For i = 0 To UBound(intArrayIndex)
		If (intArrayIndex(i) = intSelIndex) And (bolSelected(i) = True) Then
			bolSelected(i) = False
			Exit For
		End If
	Next i
	Call PopulateLists

End Sub

Sub PopulateLists()
'Назначение: пробегает по всем переменным и помещает выбранные в массив strSelVar,
'		  а не выбранные - в массив strNotSelVar.
'Предположения: не заданы
'Результат: переменные массива strSelVar появляются в списке выбранных переменных, а переменные массива strNotSelVar -
'		  в списке не выбранных
'Входные значения: не заданы
'Возвращаемые значения: не заданы

	Dim i As Integer
	Dim intNumNotSel As Integer
	Dim intNumSel As Integer
	
	intNumSel = 0
	intNumNotSel = 0
	ReDim strNotSelVar(intNumNotSel) As String
	ReDim strSelVar(intNumSel) As String
	
	'пробегаем по переменным, чтобы положить каждую в соответствующий массив в зависимости
	' от того, выбрана она или нет
	For i = 0 To UBound(bolSelected)
		If bolSelected(i) = False Then
			ReDim Preserve strNotSelVar(intNumNotSel) As String
			strNotSelVar(intNumNotSel) = strListOfVars(i)
			intArrayIndex(i) = intNumNotSel
			intNumNotSel = intNumNotSel + 1
		Else	'Переменная выбрана для анализа
			ReDim Preserve strSelVar(intNumSel) As String
			strSelVar(intNumSel) = strListOfVars(i)
			intArrayIndex(i) = intNumSel
			intNumSel = intNumSel + 1
		End If
	Next i
	
	'назначаем массивы соответствующим спискам (выбранных и не выбранных переменных).
	DlgListBoxArray "lstVarInFile", strNotSelVar()
	DlgListBoxArray "lstSelVar", strSelVar()

End Sub

Sub GetVarsFromFile()
'Назначение: импортирует имена переменных из открытого файла SPSS
'Предположения: файл данных открыт
'Результат: помещает имя переменной в список в диалоговом окне
'Входные значения: не заданы
'Возвращаемые значения: не заданы

	Dim objSPSSInfo As ISpssInfo
	Dim i As Long
	
	Set objSPSSInfo = objSpssApp.SpssInfo

	ReDim strListOfVars(objSPSSInfo.NumVariables - 1) As String
	ReDim bolSelected(objSPSSInfo.NumVariables - 1) As Boolean
	ReDim intArrayIndex(objSPSSInfo.NumVariables - 1) As Integer

	
	For i = 0 To UBound(bolSelected)
		strListOfVars(i) = objSPSSInfo.VariableAt(i)	
		bolSelected(i) = False		'Если значение = ложь (false), переменная в данный момент не выбрана
		intArrayIndex(i) = i		'определяет место переменной в списке
	Next i
	
	DlgEnable "lstVarInFile", True
	DlgEnable "lstSelVar", True
	Call PopulateLists

End Sub