Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Разбить строку

Приветствую!

Помогите, пожалуйста, решить следующую задачу...
Есть набор записей, в которых есть строки (длинные):
ID1, строка1
ID2, строка2
ID3, строка3

Необходимо разбить строки внутри записей так, чтобы получился рекордсет следующего вида:
ID1, номер строки, часть строки1
ID1, номер строки, часть строки1
ID1, номер строки, часть строки1
ID2, номер строки, часть строки2
ID2, номер строки, часть строки2
ID3, номер строки, часть строки3

И т.д... С одной строкой я решение нашел (через regexp_substr). Но что-то недопонимаю, как его прикрутить внутрь запроса...
Ответ:
env
Nikolay_Ch,

with t as (select 1 m,'строканачасти' l from dual union all
           select 2, 'другаястроканачасти' from dual)
select substr(l,(level-1)*:k,:k),'строка '||m,'часть '||level
from t
connect by level<=(length(l)/:k)+1 and prior m = m and prior dbms_random.value>0;


select substr(l,(level-1)*:k+1,:k),'строка '||m,'часть '||level
Вопрос: Алгоритм наибольшей общей последовательности двух строк

Доброе время суток.
Подскажите, пожалуйста, как улучшить алгоритм поиска наибольшей общей последовательности двух строк. Строки будут представлены двумя таблицными переменными, содеращими символ и его номер в строке. Сделал по алгоритму, найденному в интернете. Но, как то на мой взгляд, будет медленно.
То что нужно в примере создать индексы в таблицных переменных - понимаю, но всё же хотелось бы получить совет по изменению самого алгоритма. Заранее спасибо.
-- таблицы входных предложений, для примера
Declare @colWord As Table(colId int, [Char] nvarchar(1));
Declare @rowWord As Table(rowId int, [Char] nvarchar(1));
-- таблица позиций пересечений букв предложений
Declare @charIntersects As Table ([Char] nvarchar(1), rowId int, colId int, grlobalId int);
-- таблица связей позиций
Declare @ParentChild As Table (Parent_Id int, Child_Id int);
-- таблица результатов последовательностей
Declare @Sequences As Table (pathId int, Sentence nvarchar(1024), itemCount int);

-- Две исходные таблицы предложений
Insert Into @colWord Values
(1, N'ч'), (2, N'е'), (3, N'г'), (4, N'о'), (5, N'-'), (6, N'т'), (7, N'м'), (8, N' '), (9, N'в');
Insert Into @rowWord Values
(1, N'в'), (2, N' '), (3, N'м'), (4, N'о'), (5, N'т'), (6, N'ч'), (7, N'е'), (8, N'г'), (9, N'о');

-- заполняем таблицу позиций пересечений букв предложений
-- и присваиваем уникальный индекс каждой позиции
Insert Into @charIntersects
Select
       TR.[Char], TR.rowId, TC.colId,
       Row_Number() Over (Order By TR.rowId, TC.colId) As globalId
From
       @rowWord TR Inner Join @colWord TC On (TR.[Char] = TC.[Char]);

-- заполняем таблицу связей, считая предком позицию у которой
-- и строковый и столбцовый индекс одновременно меньше
-- строкового и столбцового индекса дочерних позиций
Insert Into @ParentChild
Select
       TParent.grlobalId As Parent_Id, TChild.grlobalId As Child_Id
From @charIntersects TParent Inner Join @charIntersects TChild
       On (TParent.rowId < TChild.rowId And TParent.colId < TChild.colId);

-- собираем последовательности
With Joiner (Link_Id, Sentence) As
(
       -- инициализируем начало последовательностей
       -- позициями, которые не имеют предков
       Select Child_Id, 
             Cast(TForP.[Char] + TForC.[Char] as nvarchar(1024))
       From @ParentChild TPC
             Inner Join @charIntersects TForP On (TPC.Parent_Id = TForP.grlobalId)
             Inner Join @charIntersects TForC On (TPC.Child_Id = TForC.grlobalId)
       Where Parent_Id Not In (Select Child_Id From @ParentChild)
       Union All -- дописываем в хвост буквы дочерних
       Select TChild.Child_Id,
             Cast(TParent.Sentence + TForC.[Char] as nvarchar(1024))
       From @ParentChild TChild 
             Inner Join Joiner TParent On (TChild.Parent_Id = TParent.Link_Id)
             Inner Join @charIntersects TForC On (TForC.grlobalId = TChild.Child_Id)
) -- записываем в результат, нумеруя - меньший номер у наибольшей по длине последовательности
Insert Into @Sequences
Select Row_Number() Over (Order By Len(Sentence) Desc),
       Sentence, Len(Sentence) From Joiner;

-- выводим первый результат
Select Sentence From @Sequences T Where pathId = 1;
Ответ: Доброе время суток.
кролик-зануда
а то в одном сообщении вы добавляете односимвольные совпадения, в другом - игнорируете "!"

Потому что рассматриваются два алгоритма.
1-ый – наибольшая общая последовательность символов (LCS). Символы в строках идут в том же порядке в обеих строках, но индексное расстояние между символами произвольное.
2-ой – наибольшая общая подстрока. Здесь более жёсткое ограничение – расстояние между соседними символами должно быть равно 1.
В первом приближении задачу можно описать так. Имеется эталонная строка. Её «повредили»: 5-10% символов случайным образом заменили, 5-10% удалили. Разбили на 3-4 приблизительно равные части и их случайным образом переставили.
На входе несколько таких «повреждённых» строк. Требуется определить, какая из них исходная эталонная строка.
Предварительная гипотеза: найти все LCS между «повреждённой» и «эталонной» строками и по нему определить меру сходства.
Несколько переделал алгоритм поиска LCS первого сообщения.
Declare @MaxRow int, @curRow int = 1;
-- таблицы входных предложений, для примера
Declare @colSentence As Table(colId int, [Char] nvarchar(1));
Declare @rowSentence As Table(rowId int, [Char] nvarchar(1));
-- таблица позиций пересечений букв предложений
Declare @charIntersect As Table ([Char] nvarchar(1), colId int, rankRow int, Index idx_rank (rankRow));
-- таблица результатов последовательностей
Declare @Sequences As Table 
	([Sequence] nvarchar(1024), charCount int, rankRow int, colId int,
	 Primary Key (rankRow Desc, colId Desc), Index idx_needed (charCount Desc, rankRow Desc, colId Desc));

-- Две исходные таблицы предложений
Insert Into @colSentence Values
(1, N'_'), (2, N'a'), (3, N'b'), (4, N'_'), (5, N'c'), (6, N'_'), (7, N'd'), (8, N'e'), (9, N'e');
Insert Into @rowSentence Values
(1, N'd'), (2, N'a'), (3, N'e'), (4, N' '), (5, N'b'), (6, N' '), (7, N'c'), (8, N'd'), (9, N'e');

-- заполняем таблицу позиций пересечений букв предложений, создавая сквозную нумерацию 
-- строк (какие-то символы могу и не совпадать и существующий номер будет пропущен).
Insert Into @charIntersect
Select
       TR.[Char], TC.colId,
	   Dense_Rank() Over (Order By TR.rowId) As rankId
From @rowSentence TR Inner Join @colSentence TC On (TR.[Char] = TC.[Char]);

-- Формируем опорный элемент
Insert Into @Sequences Values (N'', 0, 0, 0);
-- число строк
Select @MaxRow = Max(rankRow) From @charIntersect;
-- выбираем для каждого символа строки начальную последовательность
-- максимальной длины (по возможности ближайшую по строке и столбцу)
While (@curRow <= @MaxRow)
begin
	Insert Into @Sequences
	Select
		(Select Top(1) TSec.[Sequence] From @Sequences TSec 
		 Where TChar.rankRow > TSec.rankRow And TChar.colId > TSec.colId
		 Order By TSec.charCount Desc, TSec.rankRow Desc, TSec.colId Desc
		) + TChar.[Char] As [Sequence],
		(Select Top(1) TSec.[charCount] From @Sequences TSec 
		 Where TChar.rankRow > TSec.rankRow And TChar.colId > TSec.colId
		 Order By TSec.charCount Desc, TSec.rankRow Desc, TSec.colId Desc
		) + 1 As [charCount],
		TChar.rankRow, TChar.colId
	From @charIntersect TChar 
	Where TChar.rankRow = @curRow
	Set @curRow = @curRow + 1;
end;
Select Top(1) * From @Sequences Order By charCount Desc;

Подскажите, пожалуйста, насколько правильно настроил индексы для табличных переменных? Интересует, будет ли в цикле while поиск и вставка в @Sequences выполняться за Log(N)? И как лучше это сделать? И можно ли избавиться от while (цикл над таблицами для выборки вставки выглядит не совсем правильно с точки зрения концепции баз данных)?
По идее должно по скорости выполняться в лучшем случае (все символы в строках уникальные и строки равны) – за N*Log(N), а в худшем (в обеих строках один и тот же символ) – за N^2*Log(N). В первой реализации было. Лучшее – N^2, худшее – за N^3.
Для поиска всех последовательностей, похоже, придётся делать внешний цикл, для поиска LCS замены найденных символов на заведомо несуществующий, и поиск новой LCS, пока не получим пустую. Похоже сложность будет N^2*Log(N).
Вопрос: Как правильно добавить строки в готовую БД Access ?

Всем Доброго времени !
Есть база данных в ACCESS из 5-ти таблиц. На основе этой БД работает ПРОГРАММА Отчетов.
Опыт работы в Access – начальный уровень – общие знания как создать таблицу и ввести данные

Вопрос - Нужно добавить в базу дополнительно СТОЛБЦЫ и СТРОКИ чтобы они появилось в ПРОГРАММЕ Отчетов
В БД есть Файл СТРУКТУРЫ и Файл самой ТАБЛИЦЫ и Файл общей Информации по БД
СТОЛБЫ добавил в файле ТАБЛИЦЫ через Конструктор и заново пронумеровал НО в файле СТРУКТУРЫ они не появились и ПРОГРАММА их тоже не увидела – Видимо ПРОГРАММА берет данные из СТРУКТУРЫ
Тогда добавил эти СТОЛБЦЫ в файле СТРУКТУРЫ в разделе Stolbi в режиме Таблицы и тоже заново пронумеровал – СТОЛБЦЫ в ПРОГРАММЕ появились в нужном порядке с названиями – Получилось !

Теперь нужно добавить СТРОКИ – вопрос :
Можно ввести НОВЫЕ СТРОКИ сразу в файле СТРУКТУРЫ в разделе Stroki ?
Просто в файле СТРУКТУРЫ - там все Понятно как ввести СТРОКИ и Ключевые поля проставить соответственно каждой таблице и соответственно изменить количество строк – ВСЕ ПОНЯТНО !
А нужно ли вносить эти исправления в файле самой ТАБЛИЦЫ ? - Просто в файле ТАБЛИЦЫ – там несколько Ключевых полей и они меняются даже в пределах самих 5-ти Таблиц – т.е. в файле ТАБЛИЦЫ не понятно по какому принципу проставляются эти ключевые поля …

Более того, в Файле ТАБЛИЦЫ – сама Таблица последовательно повторяется несколько раз !!! Причем может повторяется не полностью – в некоторых моментах повторяется только часть таблицы или вообще только несколько строк … Может этот Файл Таблицы и не влияет на работу ПРОГРАММЫ и просто в него выводятся какие-либо данные - например по отчету или еще чего-нибудь …

Подскажите Пожалуйста – КАК ПРАВИЛЬНО ВВЕСТИ ДОПОЛНИТЕЛЬНЫЕ СТРОКИ ?
Если ввести строки в Файле СТРУКТУРЫ – этого будет Достаточно ? – Тем более похоже что ПРОГРАММА работает с файлом СТРУКТУРЫ – т.к. добавленные Столбцы и их названия и нумерация появились ТОЛЬКО после исправления СТРУКТУРЫ ! В СТРУКТУРЕ похоже находятся все данные по БД в т.ч. и Расчетные Формулы !
ПОДСКАЖИТЕ КАК ПРАВИЛЬНО СДЕЛАТЬ и ДОБАВИТЬ СТРОКИ ?
БЛАГОДАРЮ !

Добавлено через 23 минуты
И еще ВОПРОС - Как быстро пронумеровать строки в Поле КодИдентификатора ? - Вручную не удобно и не быстро, а строк много
Ответ: Столбцы и строки в таблицах есть. Жду ячейки
Вопрос: Вывести сумму по столбцу в строке

подскажите пожалуйста, как вывести в строку итоговую сумму по столбцу (без отдельного запроса)? м.б. кто-то знает как или существует функция какая-то (вывел через set, но неудобно)

T-SQL
1
2
3
4
5
set 'то что надо получить' = select sum(строки) from таблица
 
select строки, sum(сумма), то что надо получить
from таблица
group by строки
пример
СТРОКИсуммато что надо получить
строка 11073
строка 21073
строка 31273
строка 41673
строка 52573
Ответ:
T-SQL
1
2
3
select строки, sum(сумма), sum(sum(сумма)) over ()
from таблица
group by строки
Вопрос: Ошибка: <Method 'Cells' of object '_Global' failed> при проверке количества строк

Добрый день!
Есть код в Access, который открывает Excell-файл и загружает из него строки в свою таблицу.
Перед загрузкой стоит строка проверки количества строк в Excel:
lLastRow = Cells.SpecialCells(xlLastCell).Row


Если код запустить первый раз, то он отрабатывает успешно. При этом, в процессах Windows появляется новый процесс: EXCEL.EXE. Почему-то после завершения процедуры этот процесс не закрывается (хотя есть xlt.Close (False)).
Если сразу снова запустить эту же процедуру, то возникает ошибка: <Method 'Cells' of object '_Global' failed> на строке:
lLastRow = Cells.SpecialCells(xlLastCell).Row

При этом, естественно, в процессах появился второй EXCEL.EXE, который не закрылся из-за ошибки.

Но если не удалять эти два процесса EXCEL.EXE, а перезапустить клиента Access и затем процедуру, то всё работает корректно, процедуру можно запускать несколько раз подряд, при этом, после её отработки второй процесс EXCEL.EXE успешно открывается и закрывается, а первый просто висит...

Если НЕ перезапускать клиента Access, а в диспетчере завершить все процессы EXCEL.EXE и запустить процедуру, то появится другая ошибка: <The remote server machine does not exist or is unavaliable>.

И наконец, если перезапустить клиента и удалить ВСЕ процессы EXCEL.EXE, то опять первый раз отработает корректно...

Просьба помочь разобраться, в чём суть ошибки, почему при (с виду) одних и тех же условиях, код то работает, то нет. Может я неправильно закрываю Excel?
Заранее благодарен!

Вот сама процедура целиком:
Private Sub РисунокЗагрузитьФайл_Click()
 
Dim Sht As String
Dim ln As String
Dim sg As String
Dim tm24 As String
Dim tm48 As String
Dim Line As String
Dim m_str() As String
Dim Shd_sur As String
Dim Shd_fir As String
Dim Shd_par As String
 
Dim time24 As Date
Dim time48 As Date
 
'###############################################
 
DoCmd.SetWarnings False
DoCmd.RunSQL "delete from свод" ' удалили всё из таблицы "свод"
DoCmd.SetWarnings True
 
'#############################################
 
DoCmd.SetWarnings False
Dim file As String
                                                  
' проверяем, есть ли файл в директории:
Dim path, nameFile
path = "\\tb-fs05\Department-2\SSI\&#192;&#237;&#228;&#240;&#229;&#233;\&#211;&#208;&#194;&#202;&#202;\&#194;&#251;&#227;&#240;&#243;&#231;&#234;&#224;_CRM"
nameFile = "Создать_документ.xlsx"
If Dir(path & "\" & nameFile) = "" Then ' если файла нет, выводим сообщение и выходим из процедуры:
  MsgBox "В папке " & path & " нет файла " & filename"
  Exit Sub
Else

        file = "\\tb-fs05\Department-2\SSI\УРВКК\Выгрузка\Создать_документ.xlsx"
       
        Set xl = CreateObject("Excel.Application")
        Set xlt = xl.Workbooks.Open(file)
 
    
    Dim llastrow As Long
    Dim k As Long
   
    llastrow = Cells.SpecialCells(xlLastCell).row ' нашли количество заполненных строк в Excel
   
    
      For k = 1 To llastrow
        Shd = xlt.ActiveSheet.Cells(k + 1, 9).Value ' ФИО
        Sht = xlt.ActiveSheet.Cells(k + 1, 10).Value ' дата регистрации
        DrN = xlt.ActiveSheet.Cells(k + 1, 14).Value 'номер
        Car = xlt.ActiveSheet.Cells(k + 1, 18).Value 'этап
        sg = xlt.ActiveSheet.Cells(k + 1, 3).Value 'группа
         
             
                              
        'удаляем апостроф, если он найден в ФИО
        Shd = Replace(Shd, "'", "")
                       
        '=================================================================
        ' расчёт количества слов в ячейке:
                Dim iStr As String  'исходная строка
                Dim b As String     'строка без пробелов
                Dim x As String     'текущий символ в строке
                Dim i As Integer    'номер текущего символа
                Dim j As Integer    'счётчик пробелов
                Dim y As Integer    'количество слов
                iStr = Shd
                b = Trim(iStr)
                j = 0
                For i = 1 To Len(b)
                x = Mid(b, i, 1)
                If x = " " Then j = j + 1
                Next i
                y = j + 1 ' записали количество слов в переменную
        '====================================================================
                 
        m_str() = Split(Shd, " ")
        If Shd <> "" Then  '&#239;проверяем ячейку с ФИО на значение NULL
               
                If y = 3 Then 'если полное ФИО
               
                Shd_sur = m_str(0) ' выделили фамилию
                Shd_fir = m_str(1) ' имя
                Shd_par = m_str(2) ' отчество
               
                Set rstLine = Nothing
                 ' в таблице users нашли данного сотрудника:
                Sqltext = "Select users.surname, users.first_name, users.patronymic, users.line_id" _
                & " FROM users WHERE (CAST(surname as varchar) = '" & Shd_sur & "') And (CAST(first_name as varchar) = '" & Shd_fir & "') And (CAST (patronymic as varchar) = '" & Shd_par & "');"
                rstLine.Open Sqltext, cn, adOpenKeyset, adLockOptimistic
               
                ElseIf y = 2 Then ' если нет отчества:
               
                Shd_sur = m_str(0) ' фамилия
                Shd_fir = m_str(1) ' имя
                Shd_par = ""       ' пусто
               
                Set rstLine = Nothing
                Sqltext = "Select users.surname, users.first_name, users.patronymic, users.line_id" _
                & " FROM users WHERE (CAST(surname as varchar) = '" & Shd_sur & "') And (CAST(first_name as varchar) = '" & Shd_fir & "');"
                rstLine.Open Sqltext, cn, adOpenKeyset, adLockOptimistic
               
                End If
               
        End If
       
     
            If rstLine.RecordCount > 0 Then проверяем, найден ли сотрудник в таблице users
            If (rstLine.Fields(3) = 26) Or (rstLine.Fields(3) = 27) Then ' проверяем доп. условия
           
             If (sg = "Жалобы") Or (sg = "Претензии") Then

            If Shd Like FIO Then
        
    ' ###################### далее расчёт временных интервалов ################################
            
            
            Sht = DateAdd("h", 7, CDate(Sht))
           
            Sht = DateAdd("h", -24, CDate(Sht)) ' &#241;&#237;&#224;&#247;&#224;&#235;&#224; &#238;&#242;&#237;&#232;&#236;&#224;&#229;&#236; 24 &#247;&#224;&#241;&#224;, &#247;&#242;&#238;&#225;&#251; &#226; &#246;&#232;&#234;&#235;&#229; &#239;&#240;&#232;&#225;&#224;&#226;&#232;&#242;&#252; &#232; &#241;&#237;&#238;&#226;&#224; &#226;&#251;&#233;&#242;&#232; &#237;&#224; &#226;&#240;&#229;&#236;&#255; &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#224;&#246;&#232;&#232;
            
             Do
             Sht = DateAdd("h", 24, CDate(Sht)) 
            
             Set rstTimeReg = Nothing
            
             Sqltext = "Select id, ddmmyy, output, holiday FROM Calendar WHERE ddmmyy = '" & (Format(Sht, "yyyy-mm-dd")) & "';"
             rstTimeReg.Open Sqltext, cn, adOpenKeyset, adLockOptimistic
                            
                          
            Loop While ((rstTimeReg.Fields(2) = 1) Or (rstTimeReg.Fields(3) = 1)) 
          
             tm24 = Sht
           
             Do
             tm24 = DateAdd("h", 24, CDate(tm24))
            
             Set rstTime24 = Nothing
           
             Sqltext = "Select id, ddmmyy, output, holiday FROM Calendar WHERE ddmmyy = '" & (Format(tm24, "yyyy-mm-dd")) & "';"
             rstTime24.Open Sqltext, cn, adOpenKeyset, adLockOptimistic
                            
                          
            Loop While ((rstTime24.Fields(2) = 1) Or (rstTime24.Fields(3) = 1)) 
                         
            tm48 = tm24
                       
            Do
             tm48 = DateAdd("h", 24, CDate(tm48))
            
             Set rstTime48 = Nothing
            
             Sqltext = "Select id, ddmmyy, output, holiday FROM Calendar WHERE ddmmyy = '" & (Format(tm48, "yyyy-mm-dd")) & "';"
             rstTime48.Open Sqltext, cn, adOpenKeyset, adLockOptimistic
                            
             Loop While ((rstTime48.Fields(2) = 1) Or (rstTime48.Fields(3) = 1)) 
    '#################################################################################
                                                                     
         ' если все проверки прошли и интервалы вычислили, добавляем строку в таблицу access:
          DoCmd.RunSQL "INSERT INTO свод(ФИО,Дата, Номер, Этап, остаток_24, остаток_48) select '" & Shd & "','" & Sht & "','" & DrN & "','" & Car & "', '" & tm24 & "', '" & tm48 & "'"
       
        
        End If
        End If
        End If
        End If
               
      Next k ' перешли к следующей записи
   
 xlt.Close (False) ' закрыли Excel
 
   
End If
  
   
DoCmd.SetWarnings True
 
' обновляем поля формы:
Sqltext = "SELECT Код, ФИО, Дата, Номер, Этап, остаток_24, остаток_48" _
& " FROM свод order by CDate(остаток_48) DESC"
 
Set rstaccess_local = Nothing
rstaccess_local.Open Sqltext, CurrentProject.Connection, adOpenKeyset, adLockOptimistic
Set Me.Form.Recordset = rstaccess_local
  
End Sub
Ответ:
Akina
nik.an
Перед загрузкой стоит строка проверки количества строк в Excel:
lLastRow = Cells.SpecialCells(xlLastCell).Row

Угу... а вот если бы было явное указание, в какой книге да на каком листе использовать Cells...


Спасибо!
В итоге Ваша версия оказалась верной!
Ещё раз переделал строку на:
lLastRow = xlt.ActiveSheet.Cells.SpecialCells(xlLastCell).Row

Стало работать корректно.
Вопрос: Столбец в строку

Имеется таблица, содержащая один столбец с данными (например целочисленных, записей скажем тысячи три),
1
2
3
4
100
...
...
нужно значения всех строк закинуть в буфер обмена в виде строки через какой-нибудь разделитель, скажем / (например 1/2/3/4/100/.....)
Каким образом это сделать с максимальной производительностью?
Ответ:
Местами администратор
Имеется таблица, содержащая один столбец с данными (например целочисленных, записей скажем тысячи три),
1
2
3
4
100
...
...
нужно значения всех строк закинуть в буфер обмена в виде строки через какой-нибудь разделитель, скажем / (например 1/2/3/4/100/.....)
Каким образом это сделать с максимальной производительностью?


Из экзотики

1. Если в качестве типа данных для этого поля используется тип Numeric, то физически в файле DBF число хранится как символьная строка. Т.е. для данного типа число 123 так физически и будет хранится как 3 символа "123" с ведущими пробелами

Из этого следует, что можно просто открыть файл DBF как текстовый файл. Затем "отрезать" заголовок. А вот в качестве разделителя использовать служебный байт, в котором хранится признак удаленной записи. Можно предварительно сделать DELETE ALL, чтобы этот разделитель "проявился"

_clipText = FileToStr("MyTable.dbf")


Есть тип поля это не Numeric и не Character, то можно предварительно выгрузить таблицу в старый формат через

COPY TO ... TYPE FOX2X AS 866


2. При помощи COPY TO можно также выгрузить в текстовый файл. Поскольку у Вас один столбец, то разделителем будет два символа: перевод строки и возврат каретки. Т.е. Chr(13) + Chr(10)

select MyTab
COPY TO MyFile.txt TYPE DELIMITED
_clipText = FileToStr("MyFile.txt")


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

К сожалению, если такой "разделитель" не подходит, то замена разделителя "съест" весь выигрыш от быстрой выгрузки. Просто в FoxPro работа с большими текстовыми строками - это относительно медленная операция. Можно, конечно, поиграться с FOPEN()+FGETS(), но не уверен, что результат будет быстрее чем описанный ранее SCAN
Вопрос: Фиксированное количество строк в отчете...

Собственно сабж... Задача вроде простая, но никак не придумаю как
сделать. Нужно чтобы отчет всегда имел определенное количество строк,
независимо от количества данных. Ну, к примеру, 10 строк. Если в запросе к
отчету получается 4 строки с данными, то чтобы рисовалось еще 6 пустых
строк. Как это сделать?
Ответ: Это хороший способ (TOP), но после фильтрации он быстро деактуализировался. Поэтому есть другое простое предложение (на рисунке).

Надо создать или таблицу в БД или сетку в отчёте - с нужным Вам количеством строк. Поверх неё накладываете подчинённый отчёт с нужными вам данными и такой же высотой строк (области данных). У подчинённого (он будет называться типа ВнедренныйОтчет2000) надо включить свойства Расширение и Сжатие, а так же отключить сетку, чтобы она не дублировалась с уже существующей в первом отчёте.

На рисунке использовалось наложение на сетку в отчёте, но он может не позволить вместить столько элементов! Для этого вместо неё делаем другой подчиненный отчет, который черпает данные из порожней таблицы с N строками и ничего не выводит, кроме заветной сетки с нужным нам числом строк! Не забудьте так же включить Расширение и Сжатие.

К сообщению приложен файл. Размер - 14Kb
Вопрос: Можно ли подсчитать размер строки в байтах?

Предыстория
В Ensemble 2015 столкнулся с ошибкой SUBSCRIPT в EnsLib.SQL.Common
Система пытается кэшировать sql запросы, причём ключом массива является сам запрос.
Программисты пытаются обрезать строку до 230 символов, но если в строке появляется хотя бы один wide char (читай - кириллица), то вся строка становится wide char, значит длина строки = [кол. символов] * 2
USER>ZZDUMP "kot"
 
0000: 6B 6F 74                                                kot
USER>ZZDUMP "koт"
 
0000: 006B 006F 0442                                          koт

Я заменил последнюю букву на кириллицу и вся строка увеличилась в размере в два раза.
Таким образом, если в SQL запросе есть кириллица и размер превышает 251 байт, то получаем SUBSCRIPT в недрах ансамбля.


Вопрос
Как посчитать размер строки в байтах?
Ответ:
u78
Я заменил последнюю букву на кириллицу и вся строка увеличилась в размере в два раза.
Неверный вывод:
Документация
Therefore, on a Unicode implementation of Caché each character is counted as 2 bytes; a Unicode instance of Caché counts two bytes per character even when string contain no Unicode characters.

Проверить легко:

USER>s1="kot",s2="koт"

USER>zzdump $zcvt(s1,"O","SAME")

0000: 6B 00 6F 00 74 00 k.o.t.
USER>zzdump $zcvt(s2,"O","SAME")

0000: 6B 00 6F 00 42 04 k.o.B.

u78
Вопрос
Как посчитать размер строки в байтах?
(или $l($zcvt(строка,"O","UTF8")))

Но Вам это не поможет. Нужно смотреть в сторону максимальной длины ссылки на глобал: ,
Вопрос: Собрать данные из неск.записей в одну строку

Запрос возвращает данные (строки):
ААА | БББ |
ВВВ | ААА |
БББ | ДДД |

Как собрать их в строку, типа: "ААА, БББ, ВВВ, ДДД" (т.е. ещё и исключить повторы)?
Ответ: _Вопрос?,
+
Variant = recordset.GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)

Parameters
StringFormat
A StringFormatEnum value that specifies how the Recordset should be converted to a string. The RowDelimiter, ColumnDelimiter, and NullExpr parameters are used only with a StringFormat of adClipString.
NumRows
Optional. The number of rows to be converted in the Recordset. If NumRows is not specified, or if it is greater than the total number of rows in the Recordset, then all the rows in the Recordset are converted.
ColumnDelimiter
Optional. A delimiter used between columns, if specified, otherwise the TAB character.
RowDelimiter
Optional. A delimiter used between rows, if specified, otherwise the CARRIAGE RETURN character.
NullExpr
Optional. An expression used in place of a null value, if specified, otherwise the empty string.

Перевод Google
Параметры
StringFormat
Значение StringFormat Enum, который определяет, как Recordset должен быть преобразован в строку. Ряд Разделитель, Колонка Ограничитель и параметры NumExpr используются только с StringFormat из adClipString.
NumRows
Необязательный. Количество строк, которые будут преобразованы в Recordset. Если NumRows не указан, или если оно больше, чем общее количество строк в Recordset, то все строки в Recordset преобразуются.
ColumnDelimiter
Необязательный. Разделитель, используемый между колоннами, если указано, в противном случае символ табуляции.
RowDelimiter
Необязательный. Разделитель, используемый между строк, если указано, в противном случае символ возврата каретки символ.
NullExpr
Необязательный. Выражение используется вместо нулевого значения, если указано, в противном случае пустая строка.
Восторга не разделяю (в разрезе сабжа), будут жуткие тормоза на хоть сколько нибудь значимом количестве данных.
Имхо лучше Метод 3. Заполнение таблицы при помощи запросов (по Митину) по выше
Вопрос: Как убрать двойные переводы строк и в конце поля совсем убрать перевод строки?

Здравствуйте.

Пользователи в программе вводят текст в поле, очень часто вводят несколько перевод строк, что очень некрасиво потом выглядит.

Исходников программы нет, но я нашёл используемую хранимую процедуру, которая вносит данные из программы в БД.

Там переменная:
@text NTEXT

в которой содержится текст для дальнейшей записи в БД.

Вот хочу сделать следующее:
@text = LTRIM(RTRIM(@text))   -- убираем пробелы
@text = REPLACE(@text, char(10)+char(13)+char(10)+char(13), char(10)+char(13)) -- двойные переводы строк меняем на одинарные


Таким образом в переменной уберём по краям пробелы и двойные перевод строк.

Как теперь в конце переменной проверить перевод строки там или нет? И если там перевод строки - вырезать его(и только его, т.к. перевод строк в основном тексте убирать нельзя).
Ответ: Serg58,

во-первых, переменных типа NTEXT не бывает. Бывают, однако, параметры процедур этого типа.
Во-вторых, не все строковые функции могут правильно работать с типом NTEXT.
В-третьих, если сервер новее, чем SQL 2000, то надо перейти на тип NVARCHAR(MAX),
хотя я сомневаюсь, что вам действительно нужна длина больше 4000.
В-четвёртых, вы не "убираете по краям пробелы и двойные перевод строк".
Ибо если идут подряд 4 перевода строк, то после ваших манипуляций их останется 2, а не 1!

Кстати, если строка юникодная, то корректнее применять NCHAR(13) и NCHAR(10).

SELECT REPLACE(REPLACE(REPLACE(REPLACE(S,NCHAR(10)+NCHAR(10),NCHAR(10)+NCHAR(13)),NCHAR(13)+NCHAR(10),''),NCHAR(13),''),NCHAR(10),NCHAR(10)+NCHAR(13))
FROM
(
 SELECT LTRIM(RTRIM(STUFF(S,1,PATINDEX(N'%[^'+NCHAR(10)+N']%',S)-1,N'')))
 FROM
 (
  SELECT REVERSE(STUFF(REVERSE(S),1,PATINDEX(N'%[^'+NCHAR(10)+N']%',REVERSE(S))-1,N''))
  FROM (SELECT REPLACE(@text,NCHAR(13),NCHAR(10)))T(S)
 )T(S)
)T(S);