Pls Help me !!!!

20 отговора 372 прегледа
#1

Pls Help me !!!!

Имам следният ред:
дума1 място дума2 място дума3 място дума4 (мястото например е 4 space)
Този ред го разпечатвам.
След което идва трудното, имам още един ред който трябва да се разпечата също:
дума5 място дума6 място дума7 място дума8
Проблема е в това че незнам как да ги подравня за да може принтера да ги разпечата в 4 колони.
стринг1=дума1 място дума2 място дума3 място дума4
стринг2=дума5 място дума6 място дума7 място дума8

Размерът на думите е различен. (редовете са също динамични, както и колоните)
Изчислил съм в туипсове размерът на най дългата дума за да разбера какво разстояние да остава между думите.
Но незнам как да ги подредя за да са подравнени в колони.
Много варианти опитах но явно нито един не е верен.
1. Парснах "стринг1" намерих позицията на всяка първа буква на всяка дума, след което парсвам "стринг2" и се опитах чрез добавяне на празно място да ги наредя, но нестава по обясни ми пречини който в последствие разбрах. Оттук разбрах че това е грешния ключ от палатката.
2. Втория начин който опитах е да изчился пак в туипсове разстоянието от дума до дума, направих го има известна точност, колоните бяха като змиорка, пак "пълен ташак".
Проблема според мен е че и при двата опита се опитвам да ги наредя една под друга като използвам празно място.

Много ще ми е от полза ако някой се е сблъсквал с проблем от сходен род и знае какъв е начина да се реазлизира по-горе описания проблем.
Благодаря предварително.

Отговор
в отговор на JoreDos #2

Re: Pls Help me !!!!

Ако дължината на думите ти няма горна граница е много трудно да напишеш
читав код.
Имам работещ код,но съм го писал на Delphi и ако искаш и разбираш езика мога да ти го дам.

Отговор
в отговор на JoreDos #3

Re: Pls Help me !!!!

Да кажем, че нещо такова (пиша без да пробвам):


Dim strMasiv1() As String
Dim strMasiv2() As String

strA = "Word1dkh Word2kjhweihgfeowhgfew Word3wekjhfw Word4vvvew"
strB = "Word5ewfjmewo Word6djhfwle Word7sdxhq Word8lksjhow"

strMasiv1 = Split(strA, " ")
strMasiv2 = Split(strB, " ")

'Тук имаш 2 масива с думи, и можеш да печаташ всяка една там,
'където искаш.




Разбира се, има и по-интелигентни начини да се подравни текст. Трябва да се работи с табулатори, и да укажеш TabStop за всяка колона. Но наистина, ако нямаш ограничение на дължината на думите, трябва да направиш и проверка, за да режеш излишното, иначе се скапва цялата история.

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на Щиpлиц #4

Re: Pls Help me !!!!

Здравейте искам да Ви благодаря че сте обърнали внимание на постинга, но проблема не ми е в това как да разбия думите а как да ги подравня и разпечатам. Всички думи който са за разпечатване с в масив.
например
==========================================================
For i = 0 To how_many_col - 1
str = PropStore(i).CriterProp
str_for_print = str_for_print + HMSisNeedBeforeEacheWord(str, i, str_for_print)
Next
Printer.Print Tab(15); str_for_print
==========================================================
HMSisNeedBeforeEacheWord е функция която изчислява колко празни места да сложи пред съответната дума в зависимост на коя колона трябва да се разпечата.(така става но не са подравнени като хората разминват се с бай пиксели и като го разпечатам седи много грозно)
Незнам как да кажа на принтера че втората дума от str_for_print ще е с отстъп ТАБ(20) третата с ТАБ(40) и т.н., защото аз на Принтер.Принт подавам един "str_for_print" стринг който е съставен от няколко отделни думи както се вижда от кода горе. Като се има предвид че думите както може да са 5 на брой така 7 в зависимост от броя колони, защото ако бяха статичен брой щеше да е много по лесно
Принтер.Принт Таб(15); дума1 Таб(30);дума2 Таб(45);дума3 и т.н.
Мъчих се и с Скеъл.Х и Скеъл.У но и те нестават, защото са само за един стринг, аз няма как да укажа на втората дума от стринга друг "str_for_print" Скеъл по "х и у" на същи ред.

Отговор
в отговор на JoreDos #5

Re: Pls Help me !!!!

Здрасти,

Не си писал, че има изисквания за шрифта, така че най-простото решение, което, може би ще ти свърши работа, според мен, е да си настроиш шрифта на принтера на "Courier New". Неговите символи са с еднаква ширина, така че ти остава само да си подравниш думите в стринговете, което както подразбрах ти знаеш как да направиш. Чрез употребата на този шрифт, не ти трябва да изчисляваш, никакви широчини на думите и местоположение им. Само правиш думите в стринговете ти да са подравнени с интервали, така че да са една под друга и праскаш на принтера.
Не съм 100% сигурен в това, което ти казвам, но се надявам поне малко да съм ти помогнал.

Обаче ще е интересно да кажеш как си си решил проблема.

Бии, за да те уважават!
Отговор
в отговор на JoreDos #6

Re: Pls Help me !!!!

За съжаление и така нестава

Отговор
в отговор на JoreDos #7

Re: Pls Help me !!!!

Не става защото системата за която пиша тази възможснот за генериране на отчет предоставя възможност на потребителя да си избере шрифт с който да бъде разпечатан съответния отчет.

Отговор
в отговор на JoreDos #8

Re: Pls Help me !!!!

А бе, пич, тая система сигурно и кафе предлага?
Много екстри, к'во е това нещо

Ето ти един код, който седнах и надрасках на бързо, така че може да не е много изряден. Нямам принтер в момента и затова съм го направил да подрежда думите в самата форма:

Option Explicit

Dim arr(3, 4) As String

Private Sub Form_Load()
arr(1, 1) = "dsfgdsfg"
arr(1, 2) = "rfdtyhdffdsgh"
arr(1, 3) = "dstyewd"
arr(1, 4) = "wetrdfghwert"
arr(2, 1) = "dsfggshdsfg"
arr(2, 2) = "rfdtyhdffdsgh"
arr(2, 3) = "dstyertewd"
arr(2, 4) = "wetfdghfdghrwert"
arr(3, 1) = "dstyefdghwd"
arr(3, 2) = "wetrdfghwert"
arr(3, 3) = "dstyewtewd"

Dim lngI As Long
Dim lngJ As Long
Dim sngTextHeight As Single
Dim sngTextWidth As Single
sngTextHeight = 0
sngTextWidth = 0
For lngI = 1 To 3
For lngJ = 1 To 4
If Me.TextHeight(arr(lngI, lngJ)) > sngTextHeight Then sngTextHeight = Me.TextHeight(arr(lngI, lngJ))
If Me.TextWidth(arr(lngI, lngJ)) > sngTextWidth Then sngTextWidth = Me.TextWidth(arr(lngI, lngJ))
Next lngJ
Next lngI
sngTextWidth = sngTextWidth + Me.TextWidth(Space(4))

For lngI = 1 To 3
For lngJ = 1 To 4
Me.CurrentX = (lngJ - 1) * sngTextWidth
Me.CurrentY = (lngI - 1) * sngTextHeight
Me.Print arr(lngI, lngJ)
Next lngJ
Next lngI

End Sub

Но работи със сигурност. Думите са подредени в двумерен масив.
За теб остава да си го направиш работещ и за принтер (най-общо трябва да смениш Me с Printer). А може би ще трябва да си поиграеш и с Printer.TwipsPerPixelX и Printer.TwipsPerPixelY, не знам, не съм сигурен.

Мисля, че е това. А и преди да тестваш горният код да не забравиш да направиш AutoRedraw на формата да ти е True. Иначе нищо няма да видиш.

П.П. Ако кодът излезе неподреден ще има малко работа и за Щирлиц, но не е лошо някой да обясни на мен - невежата, как да се поства код, така че да си излиза подреден. Всъщност някъде го пишеше, но май съм го проспал.

Бии, за да те уважават!


-----------------
За да не се размества кода, който постваш - му слагаш тагове в началото и в края. Ето така:

[prе]
Option Explicit
... blah blah...
[/prе]

Това е ;о)

Редактирано от Щиpлиц на

Отговор
в отговор на пpoГЪPMИcт #9

Re: Pls Help me !!!!

Така както го е написал пpoГЪPMИcт работи, но при този код всички колони са с една и съща широчина, равна (или малко по-голяма) от дължината на най-дългата дума в цялата матрица. Опитай да промениш например
arr(1, 4) = "ofuiehjfowefoiwejofiwenofineonweonifeuihwerth" и ще разбереш за какво ти говоря.

Решението ти е следното (предполага се че не се излиза извън размерите на страница, иначе ще трябва да добавиш код който да ти разбива таблицата по страници):
1. В променливите Х и У слагаш началните позиции на принтирането съответно по хоризонталата и вертикалата.
2. Позиционираш принтера на позиция Х,У.
3. Разпечатваш всички думи от първата колона една под друга като увеличаваш У но запазваш Х (като разпечаташ нещо след това трябва отново да установиш стойността на Printer.CurrentX защото тя се променя при печата).
4. Взимаш дължината на най-дългата дума от първата колона и я слагаш в променлива с име Х.
5. Увеличаваш Х с толкова, колкото искаш да е разстоянието до следващата колона (считано от края на най-дългата дума в текущата колона).
5. Наместваш У да сочи първата колона и правиш същите операции за следващата колона и така до последната колона.

Мисля че няма да имаш проблеми този метод да го реализираш с код.
Можеш да направиш и още нещо. В отделен масив предварително да изчислиш и запишеш височините на всеки ред (ако смяташ че височините на редовете ще са различни). Ако имаш тези данни, променливата У ще я променяш със стойностите от този масив а не с константа (както се предполага в метода който ти описах).

Ако имаш някакви затруднения, може и код да ти пратя.
Добре е първо да си изпробваш кода в PictureBox (или форма, както е направил прогърмист) преди да печаташ на принтера. Дори можеш с един и същ код да постигнеш две неща - Print Preview в PictureBox и същинския печат на принтера. За целта напиши следното:


Private Sub Sub_Print(strDataArray() As String, boolPreviewOnly as Boolean)

Dim objWhereToPrint As Object

If boolPreviewOnly=True Then
objWhereToPrint=picPreviewPicture
Else
objWhereToPrint=Printer
End Sub

...
Тука следва кода за наместването и разпечатването на масива strDataArray
Като използваш:

objWhereToPrint.CurrentX=....
objWhereToPrint.CurrentY=....
...=objWhereToPrint.TextWidth(....)

и т.н.
...


Успех.

Отговор
в отговор на Гeoprи #10

Re: Pls Help me !!!!

Малко съм объркал точките (има две точки 5 но няма значение:) и от втората 5-та точка :) отиваш на точка две за да затвориш цикъла и да преминеш на следващата колона.

И в кода трябва да промениш редовете objWhereToPrint=picPreviewPicture и objWhereToPrint=Printer така:

SET objWhereToPrint=picPreviewPicture
и
SET objWhereToPrint=Printer

Отговор
в отговор на Гeoprи #11

Re: Pls Help me !!!!

Точно така - при моето решение най-дългата дума определя ширината на всички колони. И мисля, че не е кой знае какъв проблема да се преработи това. И мисля, че човека е достатъчно интелигентен, за да се оправи сам.

А за кода- писал съм го през работно време, с цел да помогна. За разлика от тебе, който не си дал никакъв код, и освен това си дал решение, което е тотално грешно, което пък от друга страна ме навежда на мисълта, че ти си нямаш никакъв хабер от печатене на таблици. А когато нещо не ти е ясно е по-добре да си замълчиш, отколкото да объркваш хората, който имат нужда от помощ. Аз така правя или поне се опитвам.
Не е все едно и също дали ще печатиш на принтер или на екрана!

В твоето решение си пренебрегнал най-основното правило при печат на таблици - Таблиците винаги се печатят по редове. Ама винаги. Това си има и някои недостатъци, но са много по-малко от тези при печатане на таблица по колони.

Нека сега си представим, че имаш таблица от 15 колони, разположена на двайсетина листа.

Първо, като печатиш по колони, 15 пъти ли ще слагаш 20-те листата, за да ти напечати всяка една колона? Все пак не забравяй, че принтера печати листа, чак след като всичко е "нарисувано" на него.

Второ да речем, че имаш вертикални разделители между колоните (вертикални линии) и си напечатал вече, първите 10 страници и на единайстата излиза много дълга дума. Тогава разделителят (вертикалната линия) на 11 страница и 10-те страници няма да съвпадат.

Трето, да речем че редовете не са с еднаква височина и горната таблица има 15 колони и 600 реда. При твоето решение масивът, съхраняващ височините на редовете ще е с размерност 600, вместо 15. А да не говорим, че съм виждал справки с над 50000 реда.

Затова правилното решение е доста по различно. (Няма да слагам код, а ще го обясня накратко).

1. Прави се масив с размерност броя на колоните.
2. Обхожда се всяка една колона и се записва максималната й ширина в масива.
3. Печати се първата страница. А след това се печати тази страница до нея (ако редът е много дълъг и трябва да има такава страница).
4. И т.н. до подледната страница.


А, и още нещо много важно. Първо се правят настройките на принтера (шрифт, големина и т.н.) и чак след това се пристъпва при определянето на широчини и височини. Това го казвам за т.2 ако колоните са с различни шрифтове и също така при печатане на ред с различна височина.

Надявам се, че съм помогнал.

Бии, за да те уважават!
Отговор
в отговор на пpoГЪPMИcт #12

Re: Pls Help me !!!!

:)
Виж какво ве неврозен...
Какво ми се оправдаваш че си бил писал кода в работно време, в извънработно време, в кенефа или не знам си къде ? :)
Решението което съм дал може лесно да се разбере че е добро в рамките на една страница, както каза, човека е достатъчно интелигентен за да се оправи сам - ТОЧНО ЗАРАДИ ТОВА НЕ СЪМ СЛОЖИЛ КОД. Няма нужда от код, това е идеята която да го провокира да я нагласи според неговите нужди.

Няма да размишлявам над примерите които описваш.

А за "хабера" който съм си нямал... Ти може би печаташ по метода за който даде код ??? Честито !

Бйй, ако можеш !

Отговор
в отговор на Гeoprи #13

Re: Pls Help me !!!!

Писал съм го през работно време, за да помогна на човека. А ти и това изглежда не можеш да напишеш, дори и през свободното си време, и затова не си сложил код.
Що не вземеш да си реализираш алгоритъма, който даде на човека, за повече от една страница - 20-тина да речем. Много съм любопитен да го видя как ще стане. Постни го като код, де? Но да е по алгоритъма, който си описал и да е точка по точка. А? Без да проверяваш предварителено ширината на думите. Аре, де, постни го на мене - отворения. Пък след като го постнеш аз
Не казвам, че не може да се направи, но ще ти свърши работното време.
Защото това твоето, си е отбиване на номер, за мене. Акъл днес всеки може да дава, но това не винаги помага

Бии, за да те уважават!
Отговор
в отговор на пpoГЪPMИcт #14

Re: Pls Help me !!!!

:)
Човече, това което съм написал е идея. Тя естествено може да претърпи развитие и да се преправи според нуждите.

И какво ми се изсилваш с тези думи:

"Много съм любопитен да го видя как ще стане. Постни го като код, де? Но да е по алгоритъма, който си описал и да е точка по точка. А? Без да проверяваш предварителено ширината на думите. Аре, де, постни го на мене - отворения."

и в следващия момент веднага ми се "застраховаш" със:
"Не казвам, че не може да се направи, но ще ти свърши работното време"

Сега се сещам нещо, което съм го правил и работи:
Печаташ на принтера първата колона до този ред, който може да стигне най-долу на страницата. Запомняш до къде си стигнал. Започваш да печаташ втората колона и после третата и така до последната. Започваш нов лист като започваш от следващия ред (който не се е събрал на предната страница)и първата колона.
Някъде в кода ако щеш може да се сложи и проверка да не се излезе "вдясно" от текущата страница и това да предвидиш.

И за каква проверка за ширината на думите ми говориш и как разбра че такава проверка липсва в моя алгоритъм ? Проверява се във всяка колона коя е най-дългата дума - погледни пак алгоритъма. Ако ще се печата на повече от една страница се проверява от всяка колона в текущата страница коя е най-дългата дума ("височината" на колоната можеш да я определиш лесно като знаеш височината на редовете - тази информация може да се вземе).

Ако много настояваш и кода ще ти напиша, само няма да го крадеш и да казваш че е твой - недей на подценяваш хората около теб за да не се окажеш в доста тъпа ситуация, която както гледам назрява за тебе.

Аз пък ще те питам, дето искаш всички възможни ситуации да обхванеш - А какво ще стане ако думата в някоя от твоите колони е с дължина 491824912876498165891625981625896123895612789356128956918561894569138456913845619834 символа които са с височина 3408957134903248562389562348956238956289347 метра ?

И стига с тази надувка че си го писал в работно време - какво си написал ?? два вложени цикъла ?

И аз съм го писал в работно време, за мен винаги е "работно време" само че не го изтъквам.

Отговор
в отговор на Гeoprи #15

Re: Pls Help me !!!!

Със караници и злобни забележки няма да стигнем до резултат. Напишете код, дайте го тук да обсъдим, и тогава ще се види кой е по-... . В майкрософт са написали цял Excel, а ние тука една страница не можем да разпечатим. Що за клуб сме?

----------------------------------
помислих, хареса ми, помислих пак...
Отговор
в отговор на Гeoprи #16

Re: Pls Help me !!!!

Единственото нещо, което исках е да кажа, че да се печати по колони е тъпо. По-правилният вариант, за мене, а и не само за мене, е да се печати по редове. Това е.

А това:
"Не казвам, че не може да се направи, но ще ти свърши работното време"
го казах не, за да се застраховам, а защото знам, че има начин да се реализира. И както забелязвам ти си намерил такъв. Браво.

И след като се заяде за "работното време" просто исках да те накарам и ти да си загубиш малко от твоето, като напишеш кода. Нищо повече. Не ти искам кода, а времето, защото се заяждаш за него. Но явно е, че от теб код няма да видим - време за код няма да загубиш, а само за дребни заяждания, и ръсене на идеи без да се замислиш, защото знам, че си умен човек и ако се беше замислил нямаше да я дадеш тази идея, а много по-добра. Добре, аз спирам да се заяждам вече. Ако ще помагаш с код на някой - помагай, ако не - недей. Проблемът си е твой. Пести си ценното време.

А за кражбата на кода не се притеснявай! Аз код реализиран по тъпи идеи (т.е. в случая - печатещ по колони) не крада. И по принцип код не крада, а само идеи. Предпочитам сам да си ги реализирам.

А това, че за теб е постоянно работно време - Браво. Дано при толкова много работа да си станал милионер вече. Ако не си, пожелавам ти го отсърце. Стискай си кода яко, внимавай някой да не ти го открадне, че от него вече разбирам бая пари си направил, щом работиш толкова много. Точно така - бъди егоист.
Аз пък съм си бедняк, но пък не ме е страх, че някой ще ми открадне кода, защото в повечето случай го раздавам безусловно. И ми е добре - спя спокойно.

А и още нещо, като стана въпрос за спане. Щом за теб винаги е работно време, значи 24 часа за теб е работно време. Е, кога спиш тогава? През работното време? Оооооо, не така. Да се спи през работно време не е никак добре. Вервай ми.

Бии, за да те уважават!
Отговор
в отговор на пpoГЪPMИcт #17

Re: Pls Help me !!!!

Хах :)

Почна се :)

От къде знаеш че съм "...защото знам, че си умен човек..." може пък да съм някой тъп олигофрен който налучква отговорите на разни въпроси за програмиране :)

Спя от време на време но това не е важно...

Ще ти Copy/Paste кода, само че той е обвързан с много други неща в програмата и не мога да ти Copy/Paste 1,8MB код. Това е код, който печата в три колони (просто клиента искаше да са три защото широчината им е малко по-малко от 1/3 от 210мм). Ако много настояваш, ще си оставя другата работа и ще ти напиша код за N колони, дано да има за какво.

(Следващия код не е решение на текущия проблема а на сходен, просто илюстрира че кода който решава проблема няма да е от няколко реда и си е трудоемка и времепоглъщаща задача)...


Public Sub Sub_Print(Optional objWhere As Object)

On Error Resume Next

Dim boolOnPicture As Boolean
Dim lngI As Long
Dim lngJ As Long
Dim lngK As Long
Dim lngY As Long
Dim strPrint As String
Dim strSplitZaiavkaLines() As String
Dim strSplitZaiavka() As String
Dim strSplitZaiavkaOnNewPage() As String
Dim intStringLine As Integer
Dim strZaiavka As String
Dim sngLeftMarginForPrint As Single
Dim sngTotal As Single
Dim intNumberOfPages As Integer
Dim intColumnToPrint As Integer
Dim colArtikyli As New Collection
Dim strColKolichestvo As String

If objWhere Is Nothing Then
Set objWhere = frmPrintPreview.picPrintPreview
boolOnPicture = True
End If

If frmPrintPreview.Visible = False Then
frmPrintPreview.Show
End If

If boolOnPicture = True Then
objWhere.Cls
Else
objWhere.ScaleMode = 6
End If

If sngPrintFontSize < 6 Then sngPrintFontSize = 6

With frmPrintPreview.picHorizontalRuler
' .Cls
For lngI = 0 To .ScaleWidth Step 10
.ForeColor = vb3DShadow
frmPrintPreview.picHorizontalRuler.Line (lngI + 5, .ScaleHeight / 3)-(lngI + 5, .ScaleHeight - .ScaleHeight / 3)
.ForeColor = vbBlack
frmPrintPreview.picHorizontalRuler.Line (lngI, 0)-(lngI, .ScaleHeight)
If lngI / 20 = Int(lngI / 20) And lngI <> 0 Then
.CurrentX = lngI - .TextWidth(CStr(lngI)) / 2
.CurrentY = (.ScaleHeight - .TextHeight(CStr(lngI))) / 2
.FontBold = True
.ForeColor = vbBlue
frmPrintPreview.picHorizontalRuler.Print CStr(lngI)
.ForeColor = vbBlack
End If
Next lngI
End With

With frmPrintPreview.picVerticalRuler
' .Cls
For lngI = 0 To .ScaleHeight Step 10
.ForeColor = vb3DShadow
frmPrintPreview.picVerticalRuler.Line (.ScaleWidth / 3, lngI + 5)-(.ScaleWidth - .ScaleWidth / 3, lngI + 5)
.ForeColor = vbBlack
frmPrintPreview.picVerticalRuler.Line (0, lngI)-(.ScaleWidth, lngI)
If lngI / 20 = Int(lngI / 20) And lngI <> 0 Then
.CurrentX = (.ScaleWidth - .TextWidth(CStr(lngI))) / 2
.CurrentY = lngI - .TextHeight(CStr(lngI)) / 2
.FontBold = True
.ForeColor = vbBlue
frmPrintPreview.picVerticalRuler.Print CStr(lngI)
.ForeColor = vbBlack
End If
Next lngI
End With

objWhere.FontSize = sngPrintFontSize
objWhere.CurrentX = sngPrintFirstColumnLeft
objWhere.CurrentY = sngPrintTopMargin

strPrint = ""
' Да се печата първо в първата колона;
sngLeftMarginForPrint = sngPrintFirstColumnLeft
intColumnToPrint = 1
intNumberOfPages = 1
'frmPrintPreview.udCurrentPage.Max = 1
'frmPrintPreview.udCurrentPage.Value = 1
'frmPrintPreview.lblNumberOfPages.Caption = "от 1"

With colPrintColumns
For lngI = 1 To .Count
' Разделяне на всеки член на колекцията с редовете на заявките с разделител strSplit1 в масива strSplitZaiavka()
strSplitZaiavka() = Split(.Item(lngI), strSplit1)
' Стринга на тази заявка става равен на НОМЕР ОБЕКТ ДАТА;_НА;_ПРИЕМАНЕ;
strZaiavka = "(" & strSplitZaiavka(0) & ") " & strSplitZaiavka(1) & " " & strSplitZaiavka(2) & vbCrLf
' Вземат се всички останали редове от strSplitZaiavka по тройки (АРТИКУЛ ЕД;.ПРОД;.ЦЕНА х КОЛИЧЕСТВО;)
sngTotal = 0
For lngJ = 2 To (UBound(strSplitZaiavka()) - 3) / 3 + 1
lngY = (lngJ - 1) * 3
' И се прибавят към стринга на тази завка с изчисление на сумата за всеки артикул (Цена по количество;)
' strZaiavka = strZaiavka & strSplitZaiavka(lngY) & " " & strSplitZaiavka(lngY + 1) & "x" & strSplitZaiavka(lngY + 2) & _
"=" & Val(strSplitZaiavka(lngY + 1)) * Val(strSplitZaiavka(lngY + 2)) & vbCrLf

' Без изчисление на сумата за всеки артикул и показване само на количеството;, не и цената;
strZaiavka = strZaiavka & strSplitZaiavka(lngY) & " " & strSplitZaiavka(lngY + 2) & vbCrLf
Err.Clear
strColKolichestvo = colArtikyli.Item(strSplitZaiavka(lngY))
If Err.Number <> 0 Then
colArtikyli.Add strSplitZaiavka(lngY + 2) & strSplit1 & strSplitZaiavka(lngY), strSplitZaiavka(lngY)
Else
colArtikyli.Remove strSplitZaiavka(lngY)
strColKolichestvo = Val(strColKolichestvo) + Val(strSplitZaiavka(lngY + 2))
colArtikyli.Add strColKolichestvo & strSplit1 & strSplitZaiavka(lngY), strSplitZaiavka(lngY)
End If
Err.Clear
sngTotal = sngTotal + Val(strSplitZaiavka(lngY + 1)) * Val(strSplitZaiavka(lngY + 2))
Next lngJ
strZaiavka = strZaiavka & "Общо сума = " & sngTotal & vbCrLf
sngTotal = 0
' Ако стринга на тази заявка излиза извън листа и текущата колона е 1...
If (objWhere.CurrentY + objWhere.TextHeight(strZaiavka) > sngPrintBottomMargin) And (intColumnToPrint = 1) Then
' ...текущата колона става 2 и текущата координата по Y се приравнява на разстоянието от горната граница на листа;
sngLeftMarginForPrint = sngPrintSecondColumnLeft
intColumnToPrint = 2
objWhere.CurrentY = sngPrintTopMargin
End If

' Ако стринга на тази заявка излиза извън листа и текущата колона е 2...
If (objWhere.CurrentY + objWhere.TextHeight(strZaiavka) > sngPrintBottomMargin) And (intColumnToPrint = 2) Then
intNumberOfPages = intNumberOfPages + 1
intColumnToPrint = 1
sngLeftMarginForPrint = sngPrintFirstColumnLeft
objWhere.CurrentY = sngPrintTopMargin
' Ако се печата на принтера се започва нова страница;
If boolOnPicture = False Then
objWhere.NewPage
objWhere.CurrentY = sngPrintTopMargin
Else
strSplitZaiavkaOnNewPage = Split(strZaiavka, vbCrLf)
For lngJ = UBound(strSplitZaiavkaLines()) To UBound(strSplitZaiavkaLines()) - UBound(strSplitZaiavkaOnNewPage()) - 1 Step -1
strSplitZaiavkaLines(lngJ) = Chr$(intNumberOfPages) & strSplitZaiavkaLines(lngJ)
Next lngJ
End If
End If

' Вземане на редовете на тази заявка за да се отпечатат един по един;
strSplitZaiavkaLines = Split(strZaiavka, vbCrLf)
For lngJ = 0 To UBound(strSplitZaiavkaLines)
strSplitZaiavkaLines(lngJ) = Chr$(1 + intNumberOfPages) & strSplitZaiavkaLines(lngJ)
Next lngJ

If boolOnPicture = True Then
' Ако се печата на картинката;...
For lngJ = 0 To UBound(strSplitZaiavkaLines)
' ...само от избраната страница;
If Val(frmPrintPreview.txtCurrentPage.Text) + 1 = Asc(Left$(strSplitZaiavkaLines(0), 1)) Then
objWhere.CurrentX = sngLeftMarginForPrint
objWhere.Print Right$(strSplitZaiavkaLines(lngJ), Len(strSplitZaiavkaLines(lngJ)) - 1)
Else
objWhere.CurrentX = sngLeftMarginForPrint
objWhere.Print
End If
Next lngJ
Else
' Ако се печата на принтера;
For lngJ = 0 To UBound(strSplitZaiavkaLines)
' ...всичко от първата до последната страница ( от първия до последния ред )
objWhere.CurrentX = sngLeftMarginForPrint
objWhere.Print Right$(strSplitZaiavkaLines(lngJ), Len(strSplitZaiavkaLines(lngJ)) - 1)
Next lngJ
End If
Next lngI
End With

strZaiavka = vbCrLf & "Количества по артикули;:" & vbCrLf
For lngK = 1 To colArtikyli.Count
strZaiavka = strZaiavka & Replace(colArtikyli.Item(lngK), strSplit1, " - ") & vbCrLf
Next lngK
' Ако количествата по артикули излизат извън листа и текущата колона е 1...
If (objWhere.CurrentY + objWhere.TextHeight(strZaiavka) > sngPrintBottomMargin) And (intColumnToPrint = 1) Then
' ...текущата колона става 2 и текущата координата по Y се приравнява на разстоянието от горната граница на листа;
sngLeftMarginForPrint = sngPrintSecondColumnLeft
intColumnToPrint = 2
objWhere.CurrentY = sngPrintTopMargin
End If

' Ако количествата по артикули излизат извън листа и текущата колона е 2...
If (objWhere.CurrentY + objWhere.TextHeight(strZaiavka) > sngPrintBottomMargin) And (intColumnToPrint = 2) Then
intNumberOfPages = intNumberOfPages + 1
intColumnToPrint = 1
sngLeftMarginForPrint = sngPrintFirstColumnLeft
objWhere.CurrentY = sngPrintTopMargin
' Ако се печата на принтера се започва нова страница;
If boolOnPicture = False Then
objWhere.NewPage
objWhere.CurrentY = sngPrintTopMargin
Else
strSplitZaiavkaOnNewPage = Split(strZaiavka, vbCrLf)
For lngJ = UBound(strSplitZaiavkaLines()) To UBound(strSplitZaiavkaLines()) - UBound(strSplitZaiavkaOnNewPage()) - 1 Step -1
strSplitZaiavkaLines(lngJ) = Chr$(intNumberOfPages) & strSplitZaiavkaLines(lngJ)
Next lngJ
End If
End If

' Вземане на редовете на тази заявка за да се отпечатат един по един;
strSplitZaiavkaLines = Split(strZaiavka, vbCrLf)
For lngJ = 0 To UBound(strSplitZaiavkaLines)
strSplitZaiavkaLines(lngJ) = Chr$(1 + intNumberOfPages) & strSplitZaiavkaLines(lngJ)
Next lngJ

If boolOnPicture = True Then
' Ако се печата на картинката;...
For lngJ = 0 To UBound(strSplitZaiavkaLines)
' ...само от избраната страница;
If Val(frmPrintPreview.txtCurrentPage.Text) + 1 = Asc(Left$(strSplitZaiavkaLines(0), 1)) Then
objWhere.CurrentX = sngLeftMarginForPrint
objWhere.Print Right$(strSplitZaiavkaLines(lngJ), Len(strSplitZaiavkaLines(lngJ)) - 1)
Else
objWhere.CurrentX = sngLeftMarginForPrint
objWhere.Print
End If
Next lngJ
Else
' Ако се печата на принтера;
For lngJ = 0 To UBound(strSplitZaiavkaLines)
' ...всичко от първата до последната страница ( от първия до последния ред )
objWhere.CurrentX = sngLeftMarginForPrint
objWhere.Print Right$(strSplitZaiavkaLines(lngJ), Len(strSplitZaiavkaLines(lngJ)) - 1)
Next lngJ
End If

frmPrintPreview.udCurrentPage.Max = intNumberOfPages
frmPrintPreview.lblNumberOfPages.Caption = "от " & CStr(intNumberOfPages)

If boolOnPicture = False Then Printer.EndDoc

End Sub



(Нещо текста в коментарите не излизаше, затова го поправих. Щирлиц)

Редактирано от Щиpлиц на

Отговор
в отговор на Гeoprи #18

Re: Pls Help me !!!!

Дааааа.

А, сега не ми остава нищо друго освен да кажа едно голямо Благодаря. Има какво да се види и научи от този код.
Сигурен съм, че работи. Аз лично няма да го тествам и да го гледам, защото нямам интерес към такъв код. Надявам се някой да го разгледа подробно и съм сигурен, че ще има положителни отзиви към него.

Еееееееей. И пак не си отдели от времето, ами мина метър с готов код. Нищо де, важното е, че ще има полза от този постинг.

И последно. Не, че се заяждам, де, въпреки, че ми е в кръвта. А и казах, че приключвам вече с тази тема, но трябваше да благодаря - И ВСЕ ПАК ТОЗИ КОД ПЕЧАТИ ПО РЕДОВЕ, ако правилно съм разбрал при беглия поглед.

А, И не разбрах какво се почна? Според мене - свърши и то по най-добрият начин за всички участници в този форум, благодарение на тебе. Благодаря още веднъж!

Бии, за да те уважават!
Отговор
в отговор на пpoГЪPMИcт #19

Re: Pls Help me !!!!

Ще ме накараш наистина да седна и да ти напиша нещо и да млъкнеш накрая.

Не е нужно да се дава код, и идея стига - човека сам ще си направи сметката дали ще му върши работа и ако трябва нещо ще преправи според неговите нужди.

Кода си работи идеално само дето е обвързан с много други неща в тази програма - просто исках да ти покажа че решението на проблема не е с няколко реда - остави човека сам да си напише кода - едва ли ти си запознат със всички изисквания към него за да му направиш код според неговите нужди. Дай му някаква идея той сам ще прецени дали ще му върши работа - а реализацията с код може да е всякаква.

Ще ти напиша някакъв код колкото да спреш да се надуваш.

Отговор
в отговор на JoreDos #20

Ето ти един код

Ето ти една подпрограма, която сигурно ще ти свърши работа (сложих много коментари):
Целия пример с проекта на ВБ е на този адрес ->[линк]



Private Sub Sub_Print(objWhere As Object, _
colColumns() As Collection, _
sngLeftMargin As Single, _
sngTopMargin As Single, _
sngBottomMargin As Single, _
sngSpaceBetweenColumns As Single)

' [email protected]

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Razpe4atva chlenovete na Array ot kolekcii po koloni
' Na ekrana, na printera, ili na dryg obekt, koito poddyrja slednite metodi i svoistva
' Print , TextWidth , CurrentX , CurrentY
' Tozi kod e prednaznachen za razpechatvaneto na edna stranica
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' objWhere moje da e ili nqkoi PictureBox (picPreview) na koito predvaritelno sa
' sinhronizirani razmerite i shrifta kakvito sa na printera,
' ili Printer, za da se izpe4ata na printera

' colColumns() e Array ot kolekcii, koito sydyrjat stringovete po koloni
' colColumns(0) sa vsichki stringove ot pyrvata kolona
' colColumns(1) sa vsichki stringove ot vtorata kolona
' i t.n.

' sngLeftMargin, sngTopMargin i sngBottomMargin sa razstoqniqta sytovetno
' ot lqvo, ot gore i ot doly na lista, do kydeto moje da se pe4ata teksta

' sngSpaceBetweenColumns e razstoqnieto mejdy kolonite

Dim lngColumnsCount As Long
Dim lngColumnsLBound As Long
Dim lngColumnsUBound As Long
Dim sngMaxColumnLength() As Single
Dim sngColumnsLeftMargin() As Single
Dim lngL As Long
Dim lngM As Long
Dim sngTemp As Single

' Opredelqne razmernostta na colColumns (broq na kolonite)
lngColumnsLBound = LBound(colColumns)
lngColumnsUBound = UBound(colColumns)
lngColumnsCount = lngColumnsUBound - lngColumnsLBound + 1

' Orazmerqvane na Array ot Single s razmera na broq na kolonite
' Kydeto shte zapazim dyljinite na nai-dylgite stringove ot vsqka kolona
ReDim sngMaxColumnLength(lngColumnsLBound To lngColumnsUBound) As Single
' Orazmerqvane na Array ot Single s razmera na broq na kolonite
' Kydeto shte pazim otmestvaneto na vsqka kolona sprqmo lqvata strana na lista
ReDim sngColumnsLeftMargin(lngColumnsLBound To lngColumnsUBound) As Single

' Opredelqne na nai-dylgiq string ot vsqka edna kolona
With objWhere
For lngL = lngColumnsLBound To lngColumnsUBound
' Vzima se dyljinata na pyrviq string ot tekyshtata kolona
sngMaxColumnLength(lngL) = .TextWidth(colColumns(lngL).Item(1))
' Sravnqva se pyrviq string ot tekyshtata kolona sys vsichki ostanali stringove do kraq na kolonata
For lngM = 2 To colColumns(lngL).Count
sngTemp = .TextWidth(colColumns(lngL).Item(lngM))
' Ako se nameri po-dylyg string
If sngMaxColumnLength(lngL) < sngTemp Then
' Maksimalnata dyljina na tekyshtata kolona se priravnqva na nego
sngMaxColumnLength(lngL) = sngTemp
End If
Next 'lngM
Next 'lngL

' Tyk veche, v sngMaxColumnLength() imame dyljinite na nai-dilgiq string ot vsqka edna kolona
' Tova vsyshtonst sa otmestvaniqta ot lqvo na vsqka edna kolona sprqmo nachaloto na predshestvashtata q
' Sega shte trqbva da izchislim otmestvaniqta nakolonite ot lqvo na lista spored dyljinite im
' Nachalata na vsichki ostanali koloni sa ravni na:
' Nachaloto na prednata kolona + shirochinata na prednata kolona + razstoqnieto mejdy kolonite
' Nachaloto na pyrvata kolona e sngLeftMargin (to se prashta na podprogramata)
sngColumnsLeftMargin(lngColumnsLBound) = sngLeftMargin
' V sngTemp shte se izchislqvat nachalata za kolonite
sngTemp = sngLeftMargin
' zapochva se ot vtorata kolona (na pyrvata veche i znaem nachaloto)
For lngL = lngColumnsLBound + 1 To lngColumnsUBound
' Yvelichava se sngTemp s shirochinata na prednata kolona i na razstoqnieto mejdy kolonite
sngTemp = sngTemp + sngMaxColumnLength(lngL - 1) + sngSpaceBetweenColumns
' Sega v sngTemp imame nachaloto na tekyshtata kolona
' I q zapisvame v masiva koito sydyrja nachalata na kolonite
sngColumnsLeftMargin(lngL) = sngTemp
Next 'lngL

' Tyk veche, v sngColumnsLeftMargin() imame nachalata, ot koito trqbva da se pechatat otdelnite koloni

' Razpechatvame po koloni
For lngL = lngColumnsLBound To lngColumnsUBound
' Ystanovqvavane na nachaloto na pechatane ot gore da e ravno na sngTopMargin (to se prashta na podprogramata)
.CurrentY = sngTopMargin
' Minavame prez vsichki stringove na tekyshtata kolona
For lngM = 1 To colColumns(lngL).Count
' Namestvame nachaloto na pechatane ot lqvo da e ravno na
' Nachaloto za tekyshtata kolona
.CurrentX = sngColumnsLeftMargin(lngL)
' Razpechatvame tekyshtiq string ot tekyshtata kolona
' Pri .Print ne moje da se polzva "With ... End With" a trqbva da se zadade tvyrdo objWhere
objWhere.Print colColumns(lngL).Item(lngM)
Next 'lngM
Next 'lngL
End With

' Ako obekta ni e Printer trqbva da zavyrshim stranicata
If TypeName(objWhere) = "Printer" Then
objWhere.EndDoc
End If

End Sub


Отговор