Day to Day

Bypassing 2K Launcher in Steam for Civilization VI

The 2K launcher broke down for my friend and I today and we are unable to run my Civilization VI game from Steam. This is so annoying. Why do they have to package in a launcher for Steam, it is just an extra and unnecessary in starting the game. Thankfully, Reddit has the answer but theirs is based on the older Steam version. Here’s what we had done to resolve the issue by skipping the launcher and running the client straight from Steam.

  1. In your Steam Library list, right-click on Civilization VI
  2. From the pull down menu, select Properties
  3. Under General, enter the game exe path in the Launch Options field
Launch Options

The default path should be the following for DX11 – “C:\Program Files (x86)\Steam\steamapps\common\Sid Meier’s Civilization VI\Base\Binaries\Win64Steam\CivilizationVI.exe” %command%

The default path should be the following for DX12 – “C:\Program Files (x86)\Steam\steamapps\common\Sid Meier’s Civilization VI\Base\Binaries\Win64Steam\CivilizationVI_DX12.exe” %command%

If the path does not work, try replacing Program File (x86) with Games. Your path will look something like this – “C:\Games\Steam\steamapps\common\Sid Meier’s Civilization VI\Base\Binaries\Win64Steam\CivilizationVI_DX12.exe” %command%

Credit: https://www.reddit.com/r/civ/comments/mlompp/psa_how_to_bypass_the_launcher_in_steam/

Please game companies, stop making dumb and useless game launchers that just crash or go nuts. We can’t even play the games properly because of that.

Coding, Day to Day

NAV2016 – How to Import Excel Data into NAV

Note: This is only for Microsoft Dynamics NAV, NOT Business Central. While the principle behind it is the same, Business Central uses different objects to achieve the intended result. What we are focused on in this post is how to import data from an excel spreadsheet to NAV (example, transfer data from excel to cash receipt journal records). This will be a brief guide on the import aspect.

Variables Required

  • ExcelBuffer – Record “ExcelBuffer” – need to declare as a global variable
  • FileManagement – Codeunit “File Management”
  • ServerFileName – Text
  • SheetName – Text
  • TotalRows – Integer
  • RowNo – Integer
  • And any other variables to store the excel cell data

Supporting Function

// Get Value At Cell Function 
LOCAL GetValueAtCell(RowNo : Integer;ColNo : Integer) : Text
IF ExcelBuffer.GET(RowNo,ColNo) THEN
  EXIT(ExcelBuffer."Cell Value as Text")
ELSE
  EXIT('');

The above function is required to get the value from a specific cell in the excel spreadsheet based on the Row and Column of the cell and return the result as a string. You will have to do the necessary conversion to other data type if you want a numeric value and so on.

Import Function

First we will need to create a function (i.e. in a codeunit) that can be called from a page to trigger this import function. In this function we will trigger the dialog for the user to select the excel spreadsheet to import and also to select which sheet to import (if there are multiple excel sheets). The code snippet for this is as shown below

// Sample Import Call Function that takes in some parameters
ImportItemJournalExcel(JournalBatchName : Code[10];JournalTemplateName : Code[10])

// Get Import File
ServerFileName := FileManagement.UploadFile('Please select import File','File');
IF ServerFileName ='' THEN
  EXIT;

// Get Sheet
SheetName := ExcelBuffer.SelectSheetsName(ServerFileName);
IF SheetName = '' THEN
  EXIT;

Additional Information: It might be possible to import a zip file of excel spreadsheets for processing and/or also to process multiple sheets in an excel file. But we will not be covering this here.

Next step is to open the excel document and get the total number of rows of data.

ExcelBuffer.LOCKTABLE;
ExcelBuffer.OpenBook(ServerFileName,SheetName);
ExcelBuffer.ReadSheet;
ExcelBuffer.RESET;
ExcelBuffer.SETCURRENTKEY("Row No.");
IF ExcelBuffer.FINDLAST THEN
  TotalRows := ExcelBuffer."Row No.";

Once we know the total number of rows, we need to identify which row to start taking data from and start looping the spreadsheet to extract the data. And in this loop, you can add the codes to insert the data to a record (example Gen. Journal Lines)

FOR RowNo:=3 TO TotalRows DO BEGIN    // Start from Row 3

  // Get Cell Data
  SampleLocationData := GetValueAtCell(RowNo,2); // Column Number 2 : Location Code
  SamplePONo := GetValueAtCell(RowNo,8); // Column Number 8 : PO Number
  SampleProdCode := GetValueAtCell(RowNo,13); // Column Number 13 : Product Code
  SampleProdDescr := GetValueAtCell(RowNo,16); // Column Number 16 : Product Description  

  //  Do any logic here (i.e. insertion)

  CustomRecord.INIT;
  CustomRecord.LocationCode := SampleLocationData;
  CustomRecord.PONo := samplePONo;
  // continue adding data as needed
  CustomRecord.INSERT();


END;

Finally to end it off.

ExcelBuffer.CloseBook;

MESSAGE('Excel Import Completed');

That’s all that there is to it.

Coding, Day to Day

Business Central – How to use PromotedActionCategories

Our intern was asking me for help on using PromotedActionCategories. She tried and she was not about to make it work. She said that no matter what captions she had placed, it just showed up as “Category 9” instead of “Request Approval”. This was how she had done it.

page 50210 "Vendor Contract"
{
    Caption = 'Vendor Contract';
    PageType = Card;
    PromotedActionCategories = 'Release, Request Approval';

...

                action(CancelApprovalRequest)
                {
                    ApplicationArea = Suite;
                    Caption = 'Cancel Approval Re&quest';
                    Image = CancelApprovalRequest;
                    Promoted = true;
                    PromotedCategory = Category9;
                    ToolTip = 'Cancel the approval request.';

...

Then this was how it was resolved.

page 50210 "Vendor Contract"
{
    Caption = 'Vendor Contract';
    PageType = Card;
    PromotedActionCategories = 'New,Process,Report,Release,Request Approval';

...
                action(CancelApprovalRequest)
                {
                    ApplicationArea = Suite;
                    Caption = 'Cancel Approval Re&quest';
                    Image = CancelApprovalRequest;
                    Promoted = true;
                    PromotedCategory = Category5;
                    ToolTip = 'Cancel the approval request.';
...

As you can see from the above example, “Category4” caption has been renamed as “Release” and “Category5” caption has been renamed as “Request Approval”.

For a clearer idea on how this was resolved, you may refer to the microsoft documentation here.

Coding, Day to Day

Business Central – Action buttons not showing up in custom page

Intern was asking around for help on an issue that she was not able to solve, and I gave her some help, since I was the only one who bothered to reply. The action buttons on her custom page were not showing up, even though she had done whatever she was supposed to. Her original codes as shown below with some portions removed for brevity.

page 50210 "Vendor Contract"
{
    Caption = 'Vendor Contract';
    PageType = Document;
    PromotedActionCategories = 'Release';
    RefreshOnActivate = true;
    SourceTable = "Vendor Contract";

    layout
    {
        area(Content)
        {
            group(GroupName)
            {
                field("Contract No."; Rec."Contract No.")
                {
                    ApplicationArea = Suite;
                }
                field("Contract Name"; Rec."Contract Name")
                {
                    ApplicationArea = Suite;
                }
                field(Status; Rec.Status)
                {
                    ApplicationArea = Suite;
                }
            }
        }
    }

    actions
    {
        area(Processing)
        {
            group(Action1)
            {

                Caption = 'Release';
                Image = ReleaseDoc;
                action(Release)
                {
                    ApplicationArea = Suite;
                    Caption = 'Re&lease';
                    Image = ReleaseDoc;
                    Promoted = true;
                }
                action(Reopen)
                {
                    ApplicationArea = Suite;
                    Caption = 'Re&open';
                    Enabled = Rec.Status <> Rec.Status::Open;
                    Image = ReOpen;
                    Promoted = true;
                }
            }
        }
    }

}
Ok, no action buttons on this one

The fix is relatively simple and quite unexpected. Somehow Business Central/NAV detects that if there are no actions tied to the button, it assumes that it is not necessary to display on the page. So, you just have to add some action triggers and it will be resolved.

And we have the buttons back online!
Coding, Day to Day

Business Central – How to allow insertion of record but not modification in a list page

An intern had asked the above question and I thought to post the answer here to help out anyone who have the same. Instead of overly complicated methods/solution as her mentors suggested, the answer is very simple. Just two lines of codes.

Code example

There is no need to set Editable flag, just assign the appropriate flags to allow for insert and disallow for modify. That is all you need to do.

InsertAllowed = true;
ModifyAllowed = false;

The screenshots below shows the result of this setting, you are able to insert new records and delete but the edit option is hidden.

Hope that this is useful!

Coding, Day to Day

Business Central – Masking password or any data fields on a page

The consultants in the company were asking around if it was possible to mask a data field on a page, similar to the password field in a login page. They were thinking it was not possible as they had never seen any implementation in their existing NAV/BC projects. And that was the cue for me to show off.

I have seen it done before in my research some time ago and it was unsurprisingly simple. It was just one line of code.

ExtendedDatatype = Masked;

How it is being used is as shown below.

        field(50; "Password"; Text[50])
        {
            Caption = 'Password';
            ExtendedDatatype = Masked;
        }

The ExtendedDatatype property allows you to control the behaviour of controls on a page. For example, to display a field as a dots (for passwords), or as an email or URL or phone number. You can refer to this microsoft documentation for more information.

The end result is as shown below.

Day to Day

How To Change Your Twitter Username

I only knew how to do this today, after all these while I had been using it. I guess it’s not very often that one had to change their username of their account. Here are the steps for Twitter (Web), at least that was how I did it.

  1. Click on the “More” button found at the left hand navigation menu
  2. Go to “Settings and privacy”
  3. Under “Your account” section, go to “Account information”
  4. You might need to re-enter your password at this point
  5. Under the “username” section, edit and change the username of your choice

Your twitter link will follow this new username too. It is that simple.