Здравствуйте. Помогите пожалуйста с разобраться с проблемой. Написал процедуру сортировки больших массивов через arraylist. Работает, сортирует, скорость вроде неплохая (1048576 элементов менее, чем за минуту ), но возникла проблема при выгрузке дат на лист. Выгружаются они в текстовом формате, чтобы получить числовой формат я заменяю точки на / (в 320 строке), но после замены оказывается, что день и месяц меняются местами, и некоторые даты (те, в которых перед первой точкой число более 12) остались текстом. Заменяю вручную через - все заменяется и получаются правильные даты. Помогите разобраться в причинах такого поведения. В принципе если 140 строку заменить на[vba]
Код
ALD.Add cell.Formula
[/vba] и 320 на[vba]
Код
.Numberformat = "dd.mm.yyyy"
[/vba] то все работает правильно, но я хочу понять почему не получается сделать это заменой. Спасибо
[vba]
Код
Option Explicit Const cnt = 65536 Sub SortRangeAL() '--------------------------------------------------------------------------------------- ' Procedure : SortRangeAL ' Author : krosav4ig ' Date : 27.10.2014 ' Purpose : '--------------------------------------------------------------------------------------- ' 'Dim ALS As New ArrayList, ALN As New ArrayList, ALD As New ArrayList, AL1 As New ArrayList 'mscorlib.tlb Dim ALS, ALN, ALD, AL1 10 Set ALS = CreateObject("System.Collections.ArrayList") 20 Set ALN = CreateObject("System.Collections.ArrayList") 30 Set AL1 = CreateObject("System.Collections.ArrayList") 40 Set ALD = CreateObject("System.Collections.ArrayList") Dim Lists(2)
Dim Rng As Range, cell As Range Dim i%, n&, j%, k&, m& 'Dim t#, t1#, t2#, t3#
50 On Error GoTo SortRange_Error 60 Set Rng = Intersect(ActiveSheet.UsedRange, ActiveSheet.[A:A]) 70 Rng.Offset(, 1).Clear 80 With Application: .ScreenUpdating = 0: .EnableEvents = 0: End With 't = timer 90 For Each cell In Rng 100 If Len(cell.Value) Then 110 If IsNumeric(cell.Value) Then 120 ALN.Add cell.Value 130 ElseIf IsDate(cell.Value) Then 140 ALD.Add cell.Value 150 Else 160 ALS.Add cell.Value 170 End If 180 End If 190 Next 't1 = timer - t: t2 = timer 200 ALS.Sort: ALD.Sort: ALN.Sort 't2 = timer - t2: t3 = timer 210 Set Lists(0) = ALD: Set Lists(1) = ALN: Set Lists(2) = ALS 220 For j = 0 To 2 230 i = 0 240 If Lists(j).Count Then 250 k = k + IIf(j, Lists(j + (j > 0)).Count, 0) 260 Do 270 n = Application.Min(cnt, Lists(j).Count - i * cnt) 280 Set AL1 = Lists(j).getrange(i * cnt - IIf(i, 1, 0), n) 290 With Rng(1).Offset(k + i * cnt, 1).Resize(n) 300 .Formula = Application.Transpose(AL1.Toarray) 310 If j = 0 Then 320 .Replace ".", "/" '<--- шо-то тут не то 330 End If 340 m = .Count 350 End With 360 i = i + 1 370 Loop While n = cnt And i < 16 380 End If 390 Next 't3 = timer - t3: t = timer - t 'MsgBox "Запись значений в ArrayList - " & t1 & Chr(10) & "Непосредственно сортировка - " & t2 & Chr(10) & _ "Вывод в диапазон - " & t3 & Chr(10) & "Итого - " & t 400 Erase Lists: Set ALS = Nothing: Set ALN = ALS: Set AL1 = ALS
SortRange_Error: 410 With Application: .ScreenUpdating = 1: .EnableEvents = 1: End With 420 If Err.Number Then MsgBox "Error " & Err.Number & " (" & Err.Description & ") in Sub SortRangeAL on line " & Erl End Sub
[/vba]
Здравствуйте. Помогите пожалуйста с разобраться с проблемой. Написал процедуру сортировки больших массивов через arraylist. Работает, сортирует, скорость вроде неплохая (1048576 элементов менее, чем за минуту ), но возникла проблема при выгрузке дат на лист. Выгружаются они в текстовом формате, чтобы получить числовой формат я заменяю точки на / (в 320 строке), но после замены оказывается, что день и месяц меняются местами, и некоторые даты (те, в которых перед первой точкой число более 12) остались текстом. Заменяю вручную через - все заменяется и получаются правильные даты. Помогите разобраться в причинах такого поведения. В принципе если 140 строку заменить на[vba]
Код
ALD.Add cell.Formula
[/vba] и 320 на[vba]
Код
.Numberformat = "dd.mm.yyyy"
[/vba] то все работает правильно, но я хочу понять почему не получается сделать это заменой. Спасибо
[vba]
Код
Option Explicit Const cnt = 65536 Sub SortRangeAL() '--------------------------------------------------------------------------------------- ' Procedure : SortRangeAL ' Author : krosav4ig ' Date : 27.10.2014 ' Purpose : '--------------------------------------------------------------------------------------- ' 'Dim ALS As New ArrayList, ALN As New ArrayList, ALD As New ArrayList, AL1 As New ArrayList 'mscorlib.tlb Dim ALS, ALN, ALD, AL1 10 Set ALS = CreateObject("System.Collections.ArrayList") 20 Set ALN = CreateObject("System.Collections.ArrayList") 30 Set AL1 = CreateObject("System.Collections.ArrayList") 40 Set ALD = CreateObject("System.Collections.ArrayList") Dim Lists(2)
Dim Rng As Range, cell As Range Dim i%, n&, j%, k&, m& 'Dim t#, t1#, t2#, t3#
50 On Error GoTo SortRange_Error 60 Set Rng = Intersect(ActiveSheet.UsedRange, ActiveSheet.[A:A]) 70 Rng.Offset(, 1).Clear 80 With Application: .ScreenUpdating = 0: .EnableEvents = 0: End With 't = timer 90 For Each cell In Rng 100 If Len(cell.Value) Then 110 If IsNumeric(cell.Value) Then 120 ALN.Add cell.Value 130 ElseIf IsDate(cell.Value) Then 140 ALD.Add cell.Value 150 Else 160 ALS.Add cell.Value 170 End If 180 End If 190 Next 't1 = timer - t: t2 = timer 200 ALS.Sort: ALD.Sort: ALN.Sort 't2 = timer - t2: t3 = timer 210 Set Lists(0) = ALD: Set Lists(1) = ALN: Set Lists(2) = ALS 220 For j = 0 To 2 230 i = 0 240 If Lists(j).Count Then 250 k = k + IIf(j, Lists(j + (j > 0)).Count, 0) 260 Do 270 n = Application.Min(cnt, Lists(j).Count - i * cnt) 280 Set AL1 = Lists(j).getrange(i * cnt - IIf(i, 1, 0), n) 290 With Rng(1).Offset(k + i * cnt, 1).Resize(n) 300 .Formula = Application.Transpose(AL1.Toarray) 310 If j = 0 Then 320 .Replace ".", "/" '<--- шо-то тут не то 330 End If 340 m = .Count 350 End With 360 i = i + 1 370 Loop While n = cnt And i < 16 380 End If 390 Next 't3 = timer - t3: t = timer - t 'MsgBox "Запись значений в ArrayList - " & t1 & Chr(10) & "Непосредственно сортировка - " & t2 & Chr(10) & _ "Вывод в диапазон - " & t3 & Chr(10) & "Итого - " & t 400 Erase Lists: Set ALS = Nothing: Set ALN = ALS: Set AL1 = ALS
SortRange_Error: 410 With Application: .ScreenUpdating = 1: .EnableEvents = 1: End With 420 If Err.Number Then MsgBox "Error " & Err.Number & " (" & Err.Description & ") in Sub SortRangeAL on line " & Erl End Sub
Sub сортировка() ' ' сортировка Макрос ' With Application: .ScreenUpdating = 0: .EnableEvents = 0: End With With Sheets("Лист1").[C4:D29].Rows .Parent.Outline.ShowLevels .OutlineLevel .Sort [D4], 2 .Parent.Outline.ShowLevels .OutlineLevel - 1 End With With Application: .ScreenUpdating = 1: .EnableEvents = 1: End With End Sub
[/vba]
[vba]
Код
Sub сортировка() ' ' сортировка Макрос ' With Application: .ScreenUpdating = 0: .EnableEvents = 0: End With With Sheets("Лист1").[C4:D29].Rows .Parent.Outline.ShowLevels .OutlineLevel .Sort [D4], 2 .Parent.Outline.ShowLevels .OutlineLevel - 1 End With With Application: .ScreenUpdating = 1: .EnableEvents = 1: End With End Sub
Sub toCSV() Dim wsh As Worksheet, wsh1 As Worksheet, wsh2 As Worksheet Dim rng1, rng2 As Range, rRow& With Application: .ScreenUpdating = 0: .EnableEvents = 0: End With On Error GoTo err Set wsh = ActiveSheet Set wsh1 = Sheets("IRR"): Set wsh2 = Sheets("CSV") Set rng1 = wsh1.[A:A].SpecialCells(xlCellTypeConstants, 1) Set rng2 = Intersect(wsh1.[O:R], rng1.EntireRow) With wsh2 rRow = Application.CountA(.[B:B]) rng2.Copy .[B1].Offset(rRow) rng1.Copy .[D1].Offset(rRow) rRow = Application.CountA(.[B:B])-1 .[A2:A3].AutoFill .[A2].Resize(rRow), 0 .[F2:I3].AutoFill .[F2:I3].Resize(rRow), 0 .[B2:E2].AutoFill .[B2:E2].Resize(rRow), 3 End With Application.CutCopyMode = 0: wsh.Activate Set wsh = Nothing: Set wsh1 = Nothing: Set wsh2 = Nothing err: With Application: .ScreenUpdating = 1: .EnableEvents = 1: End With End Sub
[/vba]
замените код в module2 на[vba]
Код
Sub toCSV() Dim wsh As Worksheet, wsh1 As Worksheet, wsh2 As Worksheet Dim rng1, rng2 As Range, rRow& With Application: .ScreenUpdating = 0: .EnableEvents = 0: End With On Error GoTo err Set wsh = ActiveSheet Set wsh1 = Sheets("IRR"): Set wsh2 = Sheets("CSV") Set rng1 = wsh1.[A:A].SpecialCells(xlCellTypeConstants, 1) Set rng2 = Intersect(wsh1.[O:R], rng1.EntireRow) With wsh2 rRow = Application.CountA(.[B:B]) rng2.Copy .[B1].Offset(rRow) rng1.Copy .[D1].Offset(rRow) rRow = Application.CountA(.[B:B])-1 .[A2:A3].AutoFill .[A2].Resize(rRow), 0 .[F2:I3].AutoFill .[F2:I3].Resize(rRow), 0 .[B2:E2].AutoFill .[B2:E2].Resize(rRow), 3 End With Application.CutCopyMode = 0: wsh.Activate Set wsh = Nothing: Set wsh1 = Nothing: Set wsh2 = Nothing err: With Application: .ScreenUpdating = 1: .EnableEvents = 1: End With End Sub
Здравствуйте. Скажите пожалуйста, можно ли как-нить прикрутить класс List(of T) из .net FW к VBA. Уж очень хочется. Честно гуглил (точнее нигмил), но ничего не нашел . Спасибо
Здравствуйте. Скажите пожалуйста, можно ли как-нить прикрутить класс List(of T) из .net FW к VBA. Уж очень хочется. Честно гуглил (точнее нигмил), но ничего не нашел . Спасибоkrosav4ig
Sub LoadCSV() Dim File_$, Path_$, strcon$, strSQL$, rsARR(), field_$ Dim cnn: Set cnn = CreateObject("ADODB.Connection") Dim rst: Set rst = CreateObject("ADODB.Recordset") Dim field xx: File_ = Application.GetOpenFilename("CSV data logs,*.csv", , "Выберите CSV файл", , False) If File_ = "False" Then If MsgBox("Хотите продолжить?", 32 Or 4, "Вы не выбрали файл!") = 6 Then GoTo xx Else: Exit Sub End If End If Path_ = Left(File_, InStrRev(File_, "\")) File_ = Mid(File_, InStrRev(File_, "\") + 1) strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path_ & ";Extended Properties=""text;HDR=Yes;FMT=Delimited"";" cnn.Open strcon strSQL = "SELECT * FROM " & File_ & ";" Set rst = cnn.Execute(strSQL) field_ = rst.fields(0).Name strSQL = "SELECT * FROM " & File_ & " where [" & field_ & "] is not null order by [" & field_ & "];" Set rst = cnn.Execute(strSQL) rsARR = rst.GetRows With [a1].Resize(UBound(Application.Index(rsARR, 1, 0)), UBound(rsARR) + 1) .Value = Application.Transpose(rsARR) End With rst.Close Set cnn = Nothing End Sub
[/vba]
Vostok, вотъ вам еще вариант [vba]
Код
Sub LoadCSV() Dim File_$, Path_$, strcon$, strSQL$, rsARR(), field_$ Dim cnn: Set cnn = CreateObject("ADODB.Connection") Dim rst: Set rst = CreateObject("ADODB.Recordset") Dim field xx: File_ = Application.GetOpenFilename("CSV data logs,*.csv", , "Выберите CSV файл", , False) If File_ = "False" Then If MsgBox("Хотите продолжить?", 32 Or 4, "Вы не выбрали файл!") = 6 Then GoTo xx Else: Exit Sub End If End If Path_ = Left(File_, InStrRev(File_, "\")) File_ = Mid(File_, InStrRev(File_, "\") + 1) strcon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Path_ & ";Extended Properties=""text;HDR=Yes;FMT=Delimited"";" cnn.Open strcon strSQL = "SELECT * FROM " & File_ & ";" Set rst = cnn.Execute(strSQL) field_ = rst.fields(0).Name strSQL = "SELECT * FROM " & File_ & " where [" & field_ & "] is not null order by [" & field_ & "];" Set rst = cnn.Execute(strSQL) rsARR = rst.GetRows With [a1].Resize(UBound(Application.Index(rsARR, 1, 0)), UBound(rsARR) + 1) .Value = Application.Transpose(rsARR) End With rst.Close Set cnn = Nothing End Sub
у объекта chart есть свойство rotation угол поворота относительно начального положения. центр вращения находится в центре диаграммы. upd. Слепил небольшой примеричк
у объекта chart есть свойство rotation угол поворота относительно начального положения. центр вращения находится в центре диаграммы. upd. Слепил небольшой примеричкkrosav4ig
Можно еще и без макроса перевести дату в число. Для этого нужно выделить нужный диапазон, нажать ctrl+ h найти - «.» заметить на «.» Заменить все [p.s.]точки вводить без кавычек
Можно еще и без макроса перевести дату в число. Для этого нужно выделить нужный диапазон, нажать ctrl+ h найти - «.» заметить на «.» Заменить все [p.s.]точки вводить без кавычекkrosav4ig
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Count > 1 Then Exit Sub If Intersect(Target, Range("B5:B30")) Is Nothing Then Exit Sub
Dim sComm As String
With Target Select Case .Value Case "nb", "b" sComm = InputBox("Ввод причины:", "Ввод причины", "Прогул") If Len(sComm) > 0 Then .ClearComments .AddComment sComm End If Case Empty .ClearComments Exit Sub Case Else .ClearComments .ClearContents MsgBox "Информация", 0 Or 64, "Заголовок" End Select End With End Sub
[/vba] немного опоздал
[vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) If Target.Count > 1 Then Exit Sub If Intersect(Target, Range("B5:B30")) Is Nothing Then Exit Sub
Dim sComm As String
With Target Select Case .Value Case "nb", "b" sComm = InputBox("Ввод причины:", "Ввод причины", "Прогул") If Len(sComm) > 0 Then .ClearComments .AddComment sComm End If Case Empty .ClearComments Exit Sub Case Else .ClearComments .ClearContents MsgBox "Информация", 0 Or 64, "Заголовок" End Select End With End Sub