Цикл для ячеек PDF всегда отключен на одну

Я пытаюсь сделать принтер этикеток со штрих-кодом через ячейки. У меня есть pdfTable с 3 столбцами. Но каждый раз, когда я пытался экспортировать pdfTable с количеством ячеек, которое не равно или не делится на 3 (это количество столбцов), количество ячеек всегда увеличивается или уменьшается на 1.

Например :

  • Попытался экспортировать 30 ячеек, которые делятся на столбцы pdfTable, равные 3 (отлично работает)

  • Пытался экспортировать 1 или 10 ячеек, которые не делятся на столбцы pdfTable, равные 3 (количество ячеек всегда отключено на 1). В результате 1 ячейка становится 2 ячейками, а 10 ячеек становятся 11 ячейками.

Я всегда проверяю, есть ли что-то не так с моим циклом, из-за которого ячейки увеличиваются на 1, но я ничего не могу найти.

Вот мой код для экспорта PDF:

Public Function print_itembarcodes(lbl169 As Label)
    Dim pdfTable As New PdfPTable(3) 'pdfTable Column Count'
    pdfTable.DefaultCell.Padding = 3
    pdfTable.WidthPercentage = 100
    pdfTable.HorizontalAlignment = Element.ALIGN_CENTER
    pdfTable.DefaultCell.Border = Rectangle.NO_BORDER
    Dim emptyCell As New PdfPCell
    emptyCell.Border = 0
    Dim count As Integer
    count = 0

    For i As Integer = 0 To Admin_Menu.BarcodePrintListGrid.Rows.Count - 1 'Read item one by one'
        Admin_Menu.Label169.Text = Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(1).Value
        Admin_Menu.Label170.Text = Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(0).Value
        Admin_Menu.Label171.Text = Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(4).Value
        Barcode.process_printbarcode(Admin_Menu.Label169)
        save_printbarcode()


        For j As Integer = 0 To Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(5).Value 'Cell quantity to be exported for one item'
            pdfTable.AddCell(create_barcodecell) 'Create a cell with barcode'
            count = count + 1
        Next

    Next

    For k As Integer = 0 To count Mod 3
        pdfTable.AddCell(emptyCell)
    Next
    count = 0

    Try

        'Exporting to PDF'
        Dim folderPath As String = "C:\Temp\"
        If Not Directory.Exists(folderPath) Then
            Directory.CreateDirectory(folderPath)
        End If
        Using stream As New FileStream(folderPath & "temp2.pdf", FileMode.Create)
            Dim pdfdoc As New Document(PageSize.A4, 15.0F, 15.0F, 10.0F, 20.0F)
            PdfWriter.GetInstance(pdfdoc, stream)
            pdfdoc.Open()
            pdfdoc.Add(pdfTable)
            pdfdoc.Close()
            stream.Close()


            System.Diagnostics.Process.Start("C:\\Temp\\temp2.pdf")

        End Using


    Catch ex As MySqlException
        MsgBox(ex.Message)
    Finally
        MysqlConn.Dispose()
    End Try

    Return True
End Function

Вот мой код для функции создания ячейки со штрих-кодом:

Public Function create_barcodecell()
    Dim SaveFileDialog1 = "D:\School\Capstone\Sta. Lucia East Bowling and Billiard Hall Management System\Item Barcodes\"
    Dim Barcode2 As Image = Image.GetInstance(SaveFileDialog1 + Admin_Menu.Label169.Text + ".png")
    Barcode2.ScaleAbsolute(170.0F, 50.0F)
    img.ScalePercent(20.0F)
    img.Alignment = iTextSharp.text.Image.ALIGN_CENTER
    Dim itemname, itemprice, itemcode As New Paragraph
    itemname.Alignment = Element.ALIGN_CENTER
    itemprice.Alignment = Element.ALIGN_CENTER
    itemcode.Alignment = Element.ALIGN_CENTER


    Dim codeFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 10)
    Dim tagFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 8)
    Dim priceFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 11)
    codeFont.Color = BaseColor.WHITE
    tagFont.Color = BaseColor.WHITE
    priceFont.Color = BaseColor.WHITE


    itemname.Add(New Chunk(Admin_Menu.Label170.Text, tagFont))
    itemprice.Add(New Chunk("P " + Admin_Menu.Label171.Text + ".00", priceFont))
    itemcode.Add(New Chunk(Admin_Menu.Label169.Text, codeFont))


    Dim pdfCell As New PdfPCell
    pdfCell.UseVariableBorders = True
    pdfCell.BackgroundColor = BaseColor.RED
    pdfCell.BorderColorLeft = BaseColor.BLACK
    pdfCell.BorderColorRight = BaseColor.BLACK
    pdfCell.BorderColorTop = BaseColor.BLACK
    pdfCell.BorderColorBottom = BaseColor.BLACK
    pdfCell.PaddingTop = 10
    pdfCell.PaddingBottom = 10
    pdfCell.PaddingLeft = 8
    pdfCell.PaddingRight = 10

    pdfCell.AddElement(img)
    pdfCell.AddElement(itemname)
    pdfCell.AddElement(Barcode2)
    pdfCell.AddElement(itemcode)
    pdfCell.AddElement(itemprice)


    Return pdfCell
End Function

person Lucifer Rodstark    schedule 30.11.2017    source источник


Ответы (1)


Цикл начался с

For j As Integer = 0 To Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(5).Value 'Cell quantity to be exported for one item'

выполняется Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(5).Value + 1 раз. Возможно, вы захотите начать со значения 1 вместо 0, чтобы избавиться от по одному.

Цикл начался с

For k As Integer = 0 To count Mod 3

выполняется (count Mod 3) + 1 раз.

Моя первая идея заключалась в том, что вы могли бы также начать со значения 1 вместо 0, в конце концов, если Count уже кратно 3, вы вообще не хотите, чтобы оно запускалось.

Однако когда я настроил упрощенную версию вашей программы, в которой я начал этот цикл с 1, я тоже получил исключение. Таким образом, я пересмотрел фактическую цель этого дополнительного цикла (который я сам рекомендовал в мом ответе на ваш предыдущий вопрос) и понял из того, что количество итераций было совершенно неправильным для начала:

Для Count = 1 нужны 2 дополнительные итерации, для Count = 2 нужна 1 дополнительная итерация, для Count = 3 не нужна, для Count = 4 нужны 2 дополнительные итерации, ...

Таким образом, нужно вообще не Count Mod 3 итераций второго цикла, а (3 - (Count Mod 3)) Mod 3 итераций, или проще

While count Mod 3 <> 0
    pdfTable.AddCell(emptyCell)
    count = count + 1
End While

что также должно подсказывать интуиция: продолжайте добавлять пустые ячейки, пока количество ячеек не станет кратным 3...

Тестовый код

Я упростил ваш код, чтобы его вообще можно было запускать, в конце концов, у меня нет того множества переменных, которые вы используете. Окончательная версия (включая исправления, упомянутые выше, первый цикл, начинающийся с 1, второй, использующий While now) был таким:

Public Sub CreateTableLuciferRodstark(filledCells As Integer, fileName As String)
    Dim pdfTable As New PdfPTable(3) 'pdfTable Column Count'
    pdfTable.DefaultCell.Padding = 3
    pdfTable.WidthPercentage = 100
    pdfTable.HorizontalAlignment = Element.ALIGN_CENTER
    pdfTable.DefaultCell.Border = Rectangle.NO_BORDER

    Dim emptyCell As New PdfPCell
    emptyCell.Border = 0

    Dim count As Integer = 0

    For j As Integer = 1 To filledCells
        pdfTable.AddCell(create_barcodecell) 'Create a cell with barcode'
        count = count + 1
    Next

    While count Mod 3 <> 0
        pdfTable.AddCell(emptyCell)
        count = count + 1
    End While

    Using stream As New FileStream(fileName, FileMode.Create)
        Dim pdfdoc As New Document(PageSize.A4, 15.0F, 15.0F, 10.0F, 20.0F)
        PdfWriter.GetInstance(pdfdoc, stream)
        pdfdoc.Open()
        pdfdoc.Add(pdfTable)
        pdfdoc.Close()
    End Using
End Sub

Public Function create_barcodecell()
    Dim pdfCell As New PdfPCell
    pdfCell.UseVariableBorders = True
    pdfCell.BackgroundColor = BaseColor.RED
    pdfCell.BorderColorLeft = BaseColor.BLACK
    pdfCell.BorderColorRight = BaseColor.BLACK
    pdfCell.BorderColorTop = BaseColor.BLACK
    pdfCell.BorderColorBottom = BaseColor.BLACK
    pdfCell.PaddingTop = 10
    pdfCell.PaddingBottom = 10
    pdfCell.PaddingLeft = 8
    pdfCell.PaddingRight = 10

    pdfCell.AddElement(New Paragraph("an item"))
    pdfCell.AddElement(New Paragraph("a code"))
    pdfCell.AddElement(New Paragraph("a price"))

    Return pdfCell
End Function

Я запустил код для заполненных ячеек от 1 до 6:

CreateTableLuciferRodstark(1, "Table1of3.pdf")
CreateTableLuciferRodstark(2, "Table2of3.pdf")
CreateTableLuciferRodstark(3, "Table3of3.pdf")
CreateTableLuciferRodstark(4, "Table4of3.pdf")
CreateTableLuciferRodstark(5, "Table5of3.pdf")
CreateTableLuciferRodstark(6, "Table6of3.pdf")

и результаты:

Таблица1из3.pdf:

Таблица1из3.pdf

Таблица2из3.pdf:

Table2of3.pdf

Таблица3из3.pdf:

введите здесь описание изображения

Таблица4из3.pdf:

введите здесь описание изображения

Таблица5из3.pdf:

введите здесь описание изображения

Таблица 6 из 3.pdf:

введите здесь описание изображения

person mkl    schedule 30.11.2017
comment
Могу я спросить, зачем вам добавлять 1 к значению, когда оно уже меньше на единицу... Если я это сделаю, это приведет к тому, что ячейки теперь будут равны двум? - person Lucifer Rodstark; 01.12.2017
comment
зачем вам добавлять 1 к значению - я бы добавил 1 к начальному значению, увеличив его с 0 до 1. Таким образом, для значения 0 больше не было бы итерации цикла. Таким образом, будет на одну итерацию меньше. - person mkl; 01.12.2017
comment
Вы имеете в виду «j как целое = 0 в 1» или «Admin_Menu.BarcodePrintListGrid.Rows(i).Cells(5).Value + 1»? Потому что если вы делаете «j как целое = 0 в 1», я уже пробовал это вчера, помните? - person Lucifer Rodstark; 01.12.2017
comment
Я помню. Но это не имеет смысла. Вчера я предложил выполнять отладку путем пошагового выполнения кода, наблюдая за тем, какой цикл действительно выполняется и как часто. Вы сделали это? Каков был результат? - person mkl; 01.12.2017
comment
Я знаю... Я включаю свой Option Strict On, который похож на отладчик в VB... Но когда я пытаюсь запустить свою систему, она работает просто отлично, без ошибок, просто отключается на одну ошибку в цикле, который не вызвать сбой .. Я также попытался передать значение счетчика в msgbox, чтобы узнать, действительно ли цикл увеличивается на единицу, и это так... - person Lucifer Rodstark; 01.12.2017
comment
Я включаю Option Strict On, который похож на отладчик в VB — нет. Этот параметр не является отладчиком, он просто обеспечивает менее грязный стиль программирования. Пошаговое выполнение программы — это нечто совершенно другое. И если вы не хотите этого делать, вы можете вместо этого использовать старый стиль отладки, добавляя вывод консоли в каждом интересном месте. - person mkl; 01.12.2017
comment
Это трудно сделать? Я не очень хорошо знаком с пошаговым выполнением кода с помощью отладчика. - person Lucifer Rodstark; 01.12.2017
comment
google.com/search?q=debugger+visual+studio должен дать вам некоторые фоны, в частности статьи msdn и видео на YouTube. - person mkl; 01.12.2017
comment
Как отладчик поможет мне, если в этом нет буквальной ошибки... Просто итерация цикла... Будет ли отладчик по-прежнему находить ее и сообщать мне, что мне делать, как официальное сообщение об ошибке? - person Lucifer Rodstark; 01.12.2017
comment
Используя отладчик, вы можете пройтись по вашей программе. Таким образом, вы можете определить, выполняет ли он для данного ввода строки программы, как вы ожидаете; кроме того, он позволяет вам проверять содержимое переменных в любой такой ситуации. С изменениями, которые я предложил в своем ответе, ваш код должен добавить в таблицу правильное количество ячеек. Как вы говорите, это не так, по-видимому, есть некоторые переменные, содержимое которых не то, что вы думаете (или неожиданно изменяются). Для анализа таких проблем вы можете использовать отладчик. - person mkl; 01.12.2017
comment
Я также думаю, что если в моем цикле используется какая-то используемая переменная, поэтому на этот раз я попытаюсь объявить другой набор переменных, а если это не сработает, я пройду через отладчик. - person Lucifer Rodstark; 01.12.2017
comment
Ах, я должен признать, что в ответе, который я дал на ваш предыдущий вопрос, была ошибка. Я исправлю это и вернусь сюда снова. - person mkl; 01.12.2017
comment
Могу я спросить, так что ошибка в нашем ответе действительно заключалась в том, что пустые ячейки вызывают одну итерацию? Это причина, по которой я не могу запустить цикл с 1? - person Lucifer Rodstark; 01.12.2017
comment
Исходный цикл с пустыми ячейками не вызывал отключение по одному, он вызывал ошибку, которую вы упомянули в комментарии к другому вопросу: Если я печатаю 1 штрих-код, он говорит, что pdfTable пуст. потому что я начал с 1, поэтому можно сказать, что это была причина, по которой вы не могли начать цикл с 1. Отклонение на единицу было вызвано циклом j, начинающимся с 0. - person mkl; 01.12.2017
comment
Но у меня есть DataGridView для каждого элемента, верно? Итак, мой код прав в отношении сброса счетчика до 0, если весь элемент был отсканирован и весь цикл выполнен... - person Lucifer Rodstark; 01.12.2017
comment
Вы можете установить его на что угодно, так как после этого он больше не используется. - person mkl; 01.12.2017
comment
Спасибо, бро!!! Теперь это работает... Спасибо, что помогли мне, несмотря на то, что я получаю отрицательные голоса по своим вопросам. До следующего раза - person Lucifer Rodstark; 01.12.2017