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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
| Private Const DATABASE_SHEET_NAME As String = "База данных"
Private Const LOG_SHEET_NAME As String = "Журнал изменений"
Private currentRow As Long
Private lastRow As Long
Private Sub UserForm_Initialize()
'*** Дата и время опроса ***
txtSurveyDate.Text = Format(Now(), "dd.mm.yyyy hh:mm:ss")
txtSurveyDate.Enabled = False 'Блокируем возможность редактирования
'*** ФИО проводившего опрос ***
txtSurveyConductedBy.Text = Application.UserName
txtSurveyConductedBy.Enabled = False 'Блокируем возможность редактирования
cboOwnerUser.Clear
cboOwnerUser.AddItem "Владелец"
cboOwnerUser.AddItem "Пользователь"
cboConfirmation.Clear
cboConfirmation.AddItem "Оценка не подтверждена"
cboConfirmation.AddItem "Оценка подтверждена"
cboReasonLowRating.Clear
cboReasonLowRating.AddItem "Интернет"
cboReasonLowRating.AddItem "Продукт/тариф"
cboReasonLowRating.AddItem "Продукт/услуга"
cboReasonLowRating.AddItem "Связь"
cboReasonLowRating.AddItem "Связь/интернет"
cboReasonLowRating.AddItem "Начисление"
cboReasonLowRating.AddItem "Обслуживание"
cboReasonLowRating.AddItem "Другое"
cboReasonLowRating.AddItem "Нет"
cboGender.Clear
cboGender.AddItem "М"
cboGender.AddItem "Ж"
cboStatus.Clear
cboStatus.AddItem "В работе"
cboStatus.AddItem "Закрыто"
cboResult.Clear
cboResult.AddItem "Стал промоутером"
cboResult.AddItem "Стал нейтралом"
cboResult.AddItem "Остался детрактором"
cboResult.AddItem "Ответ по SMS"
cboResult.AddItem "Требуется повторный звонок"
cboResult.AddItem "Отказ от разговора"
cboResult.AddItem "Не предоставил данные"
cboQuestionResolution.Clear
cboQuestionResolution.AddItem "Решен"
cboQuestionResolution.AddItem "Не решен"
cboQuestionResolution.AddItem "Будет решен"
cboQuestionResolution.AddItem "Вопросов нет"
cboArea.Clear
cboArea.AddItem "Ташкент.обл."
cboArea.AddItem "Сурхандарья"
cboArea.AddItem "Каракалпак"
cboArea.AddItem "Сырдарья"
cboArea.AddItem "Бухара"
cboArea.AddItem "Наманган"
cboArea.AddItem "Фергана"
cboArea.AddItem "Андижан"
cboArea.AddItem "Хорезм"
cboArea.AddItem "Джиззак"
cboArea.AddItem "Ташкент"
cboArea.AddItem "Самарканд"
cboArea.AddItem "Кашкадаря"
cboArea.AddItem "Навои"
With cboProblem
.AddItem "0"
.AddItem "1"
End With
cboRatingSurvey.Clear
Dim i As Integer
For i = 0 To 10
cboRatingSurvey.AddItem i
Next i
ClearForm
End Sub
Private Sub ClearForm()
txtAssessmentDate.Text = ""
txtSubscriberName.Text = ""
txtSubscriberNumber.Text = ""
txtReasonDetails.Text = ""
txtNextSteps.Text = ""
txtMeasuresTaken.Text = ""
txtBSNumber.Text = ""
txtBSState.Text = ""
txtRegion.Text = ""
txtCommentsResults.Text = ""
txtTicketNumber.Text = ""
txtTariff.Text = ""
cboOwnerUser.Value = ""
cboReasonLowRating.Value = ""
cboConfirmation.Value = ""
cboGender.Value = ""
cboArea.Value = ""
cboRatingSurvey.Value = ""
cboStatus.Value = ""
cboResult.Value = ""
cboQuestionResolution.Value = ""
cboProblem.Value = ""
End Sub
Private Sub cmdFirst_Click()
With GetDatabaseSheet()
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
End With
If lastRow < 2 Then
MsgBox "В базе данных нет записей.", vbInformation
Exit Sub
End If
If currentRow = 2 Then
MsgBox "Это первая запись.", vbInformation
Else
currentRow = 2
LoadDataToForm
End If
End Sub
Private Sub cmdPrevious_Click()
With GetDatabaseSheet()
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
End With
If lastRow < 2 Then
MsgBox "В базе данных нет записей.", vbInformation
Exit Sub
End If
If currentRow > 2 Then
currentRow = currentRow - 1
LoadDataToForm
Else
MsgBox "Это первая запись.", vbInformation
End If
End Sub
Private Sub cmdNext_Click()
With GetDatabaseSheet()
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
End With
If lastRow < 2 Then
MsgBox "В базе данных нет записей.", vbInformation
Exit Sub
End If
If currentRow < lastRow Then
currentRow = currentRow + 1
LoadDataToForm
Else
MsgBox "Это последняя запись.", vbInformation
End If
End Sub
Private Sub cmdLast_Click()
With GetDatabaseSheet()
lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
End With
If lastRow < 2 Then
MsgBox "В базе данных нет записей.", vbInformation
Exit Sub
End If
If currentRow = lastRow Then
Dim ws As Worksheet
Set ws = GetDatabaseSheet()
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
currentRow = 0
ClearForm
txtSurveyDate.Text = Format(Now(), "dd.mm.yyyy hh:mm:ss")
txtSurveyConductedBy.Text = Application.UserName
LoadDataToForm
lblID.caption = "ID:"
MsgBox "Можете вводить новые дынные по опросу", vbInformation
Else
currentRow = lastRow
LoadDataToForm
MsgBox "Это последняя запись.", vbInformation
End If
End Sub
Private Sub LoadDataToForm()
Dim ws As Worksheet
Set ws = GetDatabaseSheet()
If currentRow < 2 And currentRow <> 0 Then
MsgBox "Недопустимое значение currentRow: " & currentRow, vbCritical
Exit Sub
End If
With ws
If currentRow > 0 Then
lblID.caption = "ID: " & .Cells(currentRow, 2).Value
txtSubscriberName.Text = .Cells(currentRow, 1).Value
txtSubscriberNumber.Text = .Cells(currentRow, 3).Value
txtTariff.Text = .Cells(currentRow, 4).Value
txtAssessmentDate.Text = Format(.Cells(currentRow, 5).Value, "dd.mm.yyyy")
'*** Устанавливаем дату и время из базы данных
txtSurveyDate.Text = Format(.Cells(currentRow, 6).Value, "dd.mm.yyyy hh:mm:ss")
cboOwnerUser.Value = .Cells(currentRow, 7).Value
cboReasonLowRating.Value = .Cells(currentRow, 8).Value
cboConfirmation.Value = .Cells(currentRow, 9).Value
cboGender.Value = .Cells(currentRow, 10).Value
txtReasonDetails.Text = .Cells(currentRow, 11).Value
txtNextSteps.Text = .Cells(currentRow, 12).Value
txtMeasuresTaken.Text = .Cells(currentRow, 13).Value
txtBSNumber.Text = .Cells(currentRow, 14).Value
txtBSState.Text = .Cells(currentRow, 15).Value
cboProblem.Value = CStr(.Cells(currentRow, 16).Value)
cboArea.Value = .Cells(currentRow, 17).Value
txtRegion.Text = .Cells(currentRow, 18).Value
txtCommentsResults.Text = .Cells(currentRow, 19).Value
cboRatingSurvey.Value = .Cells(currentRow, 20).Value
cboStatus.Value = .Cells(currentRow, 21).Value
cboResult.Value = .Cells(currentRow, 22).Value
cboQuestionResolution.Value = .Cells(currentRow, 24).Value
txtSurveyConductedBy.Text = .Cells(currentRow, 25).Value
txtTicketNumber.Text = .Cells(currentRow, 26).Value
Else
lblID.caption = "ID:"
End If
End With
End Sub
Private Sub btnSave_Click()
Dim ws As Worksheet, logWs As Worksheet
Dim assessmentDate As Date, surveyDate As Date
Dim rating As Integer, newID As Long
Dim logRow As Long, editCol As Long
Dim isNumericValid As Boolean
Dim i As Long
Dim idToFind As Long, foundRow As Long
Dim lastColumn As Long
' --- Получаем листы ---
Set ws = GetDatabaseSheet()
Set logWs = GetLogSheet()
'=== Проверка формата даты и преобразование ============================
If Not IsDate(txtAssessmentDate.Text) Then
MsgBox "Неверный формат даты в поле 'Дата оценки'", vbExclamation
Exit Sub
End If
assessmentDate = CDate(txtAssessmentDate.Text)
' === проверка, что оценка это число от 0 до 10 =========================
If Not IsNumeric(cboRatingSurvey.Value) Then
MsgBox "Оценка по итогу опроса должна быть числом от 0 до 10.", vbCritical, "Ошибка ввода"
Exit Sub
End If
rating = CInt(cboRatingSurvey.Value)
If rating < 0 Or rating > 10 Then
MsgBox "Оценка по итогу опроса должна быть числом от 0 до 10.", vbCritical, "Ошибка ввода"
Exit Sub
End If
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
'=== Записываем данные =================================================
If currentRow > 1 And currentRow <= lastRow Then 'Редактируем запись
ws.Cells(currentRow, 1).Value = txtSubscriberName.Text
ws.Cells(currentRow, 3).Value = txtSubscriberNumber.Text
ws.Cells(currentRow, 4).Value = txtTariff.Text
ws.Cells(currentRow, 16).Value = cboProblem.Value
ws.Cells(currentRow, 7).Value = cboOwnerUser.Value
ws.Cells(currentRow, 8).Value = cboReasonLowRating.Value
ws.Cells(currentRow, 9).Value = cboConfirmation.Value
ws.Cells(currentRow, 10).Value = cboGender.Value
ws.Cells(currentRow, 11).Value = txtReasonDetails.Text
ws.Cells(currentRow, 12).Value = txtNextSteps.Text
ws.Cells(currentRow, 13).Value = txtMeasuresTaken.Text
ws.Cells(currentRow, 14).Value = txtBSNumber.Text
ws.Cells(currentRow, 15).Value = txtBSState.Text
ws.Cells(currentRow, 17).Value = cboArea.Value
ws.Cells(currentRow, 18).Value = txtRegion.Text
ws.Cells(currentRow, 19).Value = txtCommentsResults.Text
ws.Cells(currentRow, 20).Value = rating
ws.Cells(currentRow, 21).Value = cboStatus.Value
ws.Cells(currentRow, 22).Value = cboResult.Value
ws.Cells(currentRow, 24).Value = cboQuestionResolution.Value
ws.Cells(currentRow, 25).Value = txtSurveyConductedBy.Text 'Провёл опрос
ws.Cells(currentRow, 26).Value = txtTicketNumber.Text 'Номер заявки
ws.Cells(currentRow, 5).Value = assessmentDate
'Ищем запись в журнале по ID
idToFind = ws.Cells(currentRow, 2).Value 'ID записи в базе данных
foundRow = 0
'Проходим по всем записям в журнале, начиная со второй строки (первая - заголовки)
For i = 2 To logWs.Cells(logWs.Rows.Count, "A").End(xlUp).Row
If logWs.Cells(i, 1).Value = idToFind Then 'Если ID совпадает
foundRow = i 'Запоминаем номер строки
Exit For 'Выходим из цикла
End If
Next i
If foundRow > 0 Then 'Если запись с таким ID найдена в журнале
'Определяем последнюю колонку с данными в этой строке
lastColumn = logWs.Cells(foundRow, logWs.Columns.Count).End(xlToLeft).Column
'Находим первую свободную колонку для записи информации о редактировании
editCol = lastColumn + 1
'Записываем имя пользователя, который редактировал данные
logWs.Cells(foundRow, editCol).Value = Application.UserName
'Записываем время редактирования в соседнюю ячейку
logWs.Cells(foundRow, editCol + 1).Value = Now()
'Применяем жирную границу к обеим ячейкам
With logWs.Range(logWs.Cells(foundRow, editCol), logWs.Cells(foundRow, editCol + 1)).Borders
.LineStyle = xlContinuous
.Weight = xlMedium
End With
End If
MsgBox "Успешно отредактировано!", vbInformation
LoadDataToForm
Else 'Добавляем новую запись
If Application.WorksheetFunction.CountA(ws.Columns("A")) > 1 Then
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
newID = ws.Cells(lastRow, 2).Value + 1
Else
newID = 1
End If
ws.Cells(lastRow + 1, 1).Value = txtSubscriberName.Text
ws.Cells(lastRow + 1, 2).Value = newID
ws.Cells(lastRow + 1, 3).Value = txtSubscriberNumber.Text
ws.Cells(lastRow + 1, 4).Value = txtTariff.Text
ws.Cells(lastRow + 1, 16).Value = cboProblem.Value
ws.Cells(lastRow + 1, 7).Value = cboOwnerUser.Value
ws.Cells(lastRow + 1, 8).Value = cboReasonLowRating.Value
ws.Cells(lastRow + 1, 9).Value = cboConfirmation.Value
ws.Cells(lastRow + 1, 10).Value = cboGender.Value
ws.Cells(lastRow + 1, 11).Value = txtReasonDetails.Text
ws.Cells(lastRow + 1, 12).Value = txtNextSteps.Text
ws.Cells(lastRow + 1, 13).Value = txtMeasuresTaken.Text
ws.Cells(lastRow + 1, 14).Value = txtBSNumber.Text
ws.Cells(lastRow + 1, 15).Value = txtBSState.Text
ws.Cells(lastRow + 1, 17).Value = cboArea.Value
ws.Cells(lastRow + 1, 18).Value = txtRegion.Text
ws.Cells(lastRow + 1, 19).Value = txtCommentsResults.Text
ws.Cells(lastRow + 1, 20).Value = rating
ws.Cells(lastRow + 1, 21).Value = cboStatus.Value
ws.Cells(lastRow + 1, 22).Value = cboResult.Value
ws.Cells(lastRow + 1, 24).Value = cboQuestionResolution.Value
ws.Cells(lastRow + 1, 25).Value = txtSurveyConductedBy.Text 'Провёл опрос
ws.Cells(lastRow + 1, 26).Value = txtTicketNumber.Text 'Номер заявки
ws.Cells(lastRow + 1, 5).Value = assessmentDate
ws.Cells(lastRow + 1, 6).Value = CDate(txtSurveyDate.Text)
logRow = logWs.Cells(logWs.Rows.Count, "A").End(xlUp).Row + 1
logWs.Cells(logRow, 1).Value = newID
logWs.Cells(logRow, 2).Value = txtSurveyConductedBy.Text
logWs.Cells(logRow, 3).Value = txtSubscriberNumber.Text
logWs.Cells(logRow, 4).Value = txtSurveyDate.Text
logWs.Cells(logRow, 5).Value = Now()
currentRow = 0
End If
If currentRow = 0 Then
ClearForm
txtSurveyDate.Text = Format(Now(), "dd.mm.yyyy hh:mm:ss")
txtSurveyConductedBy.Text = Application.UserName
lblID.caption = "ID:"
End If
LoadDataToForm
If currentRow = 0 Then
LoadDataToForm
End If
MsgBox "Данные сохранены!", vbInformation
End Sub
Private Sub cmdNew_Click()
Dim ws As Worksheet
Set ws = GetDatabaseSheet()
ClearForm
txtSurveyDate.Text = Format(Now(), "dd.mm.yyyy hh:mm:ss")
txtSurveyConductedBy.Text = Application.UserName
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
currentRow = 0
LoadDataToForm
lblID.caption = "ID:"
End Sub
Private Function GetDatabaseSheet() As Worksheet
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Sheets(DATABASE_SHEET_NAME)
On Error GoTo 0
If ws Is Nothing Then
Set ws = ThisWorkbook.Sheets.Add
ws.name = DATABASE_SHEET_NAME
With ws
.Cells(1, 1).Value = "Имя абонента"
.Cells(1, 2).Value = "ID"
.Cells(1, 3).Value = "Номер абонента"
.Cells(1, 4).Value = "Тариф"
.Cells(1, 5).Value = "Дата оценки"
.Cells(1, 6).Value = "Дата и время звонка"
.Cells(1, 7).Value = "Владелец / Пользователь"
.Cells(1, 8).Value = "Причина низкой оценки"
.Cells(1, 9).Value = "Подтверждение"
.Cells(1, 10).Value = "Пол"
.Cells(1, 11).Value = "Причина недовольства (детали)"
.Cells(1, 12).Value = "Следующие шаги"
.Cells(1, 13).Value = "Принятые меры"
.Cells(1, 14).Value = "Номер БС"
.Cells(1, 15).Value = "Состояние БС"
.Cells(1, 16).Value = "Проблема есть (1)/Нет (0)"
.Cells(1, 17).Value = "Область"
.Cells(1, 18).Value = "Район"
.Cells(1, 19).Value = "Комментарии по итогам"
.Cells(1, 20).Value = "Оценка по итогу опроса"
.Cells(1, 21).Value = "Статус"
.Cells(1, 22).Value = "Результат"
.Cells(1, 23).Value = "СМС ответ - шаблон"
.Cells(1, 24).Value = "Решение вопроса"
.Cells(1, 25).Value = "ФИО проводившего"
.Cells(1, 26).Value = "Заявка"
End With
End If
Set GetDatabaseSheet = ws
End Function
Private Function GetLogSheet() As Worksheet
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Sheets(LOG_SHEET_NAME)
On Error GoTo 0
If ws Is Nothing Then
Set ws = ThisWorkbook.Sheets.Add
ws.name = LOG_SHEET_NAME
With ws
.Cells(1, 1).Value = "ID"
.Cells(1, 2).Value = "ФИО проводившего"
.Cells(1, 3).Value = "Номер абонента"
.Cells(1, 4).Value = "Дата и время звонка"
.Cells(1, 5).Value = "Дата и время создания"
End With
End If
Set GetLogSheet = ws
End Function
Private Sub Workbook_Open()
Dim ws As Worksheet
On Error Resume Next
Set ws = ThisWorkbook.Sheets(LOG_SHEET_NAME)
On Error GoTo 0
If Not ws Is Nothing Then
ws.Visible = xlSheetHidden
End If
End Sub |